apply()
是 Pandas 中最灵活且强大的函数之一,它允许你 自定义操作逻辑,并将其应用到 DataFrame 或 Series 的行、列或分组中。本文通过实战案例,帮你彻底掌握 apply()
的核心用法。
一、基础概念:什么是 apply()?
apply()
的核心作用是:对数据集的某一部分(行、列、分组)执行自定义函数,并将结果自动整合返回。
它的行为取决于调用对象:
调用对象 | 行为 |
---|---|
Series | 对每个元素执行函数 |
DataFrame | 对每列(默认 axis=0 )或每行(axis=1 )执行函数 |
GroupBy 对象 | 对每个分组执行函数,结果自动合并 |
二、核心用法详解
1. 对 Series 使用 apply()
场景:对一列数据进行元素级操作。
Python复制
import pandas as pd
# 示例数据
s = pd.Series([1, 2, 3, 4])
# 将每个元素平方
s_squared = s.apply(lambda x: x ** 2)
print(s_squared)
# 输出:
# 0 1
# 1 4
# 2 9
# 3 16
2. 对 DataFrame 使用 apply()
场景:对 DataFrame 的行或列执行操作。
Python复制
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
})
# 对每列求和(默认 axis=0)
col_sums = df.apply(lambda col: col.sum())
print(col_sums) # 输出: A 6, B 15
# 对每行求平均值(axis=1)
row_means = df.apply(lambda row: row.mean(), axis=1)
print(row_means) # 输出: 0 2.5, 1 3.5, 2 4.5
3. 对 GroupBy 对象使用 apply()
场景:对分组后的数据执行复杂操作。
Python复制
# 示例数据(学生成绩)
df = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Alice', 'Bob'],
'Score': [85, 90, 78, 92]
})
# 按姓名分组,取每组最高分
def top_score(group):
return group.sort_values(by='Score', ascending=False).head(1)
result = df.groupby('Name').apply(top_score)
print(result)
# 输出:
# Name Score
# Name
# Alice 0 Alice 85
# Bob 1 Bob 90
# 3 Bob 92
三、进阶技巧与实战案例
1. 传递额外参数
通过 args
或 kwargs
向函数传递额外参数:
Python复制
def add_value(x, constant=0):
return x + constant
# 对列 A 的每个元素加 10
df['A_plus'] = df['A'].apply(add_value, constant=10)
2. 处理多列数据
若函数需要多列数据,需在 DataFrame 上使用 axis=1
:
Python复制
# 计算两列之和
df['Sum'] = df.apply(lambda row: row['A'] + row['B'], axis=1)
3. 分组后复杂操作
案例:统计每组数据的统计指标(均值、最大值):
Python复制
def group_stats(group):
return pd.Series({
'Mean': group.mean(),
'Max': group.max()
})
result = df.groupby('Name')['Score'].apply(group_stats)
print(result)
# 输出:
# Mean Max
# Name
# Alice 81.5 85
# Bob 91.0 92
四、性能优化与替代方案
1. 性能注意事项
-
避免在大数据集上使用 apply:Pandas 的向量化操作(如
+
,sum()
)比apply
快得多。 -
使用内置函数替代:如
df['A'] + 10
优于df['A'].apply(lambda x: x+10)
。
2. 替代方案对比
场景 | 推荐方法 | 优势 |
---|---|---|
元素级简单操作 | 向量化运算(如 + , * ) | 速度快 |
分组聚合(如求和、均值) | groupby.agg() | 语法简洁,性能更优 |
复杂分组操作 | groupby.apply() | 灵活性最高 |
五、常见误区与解决方案
1. 忽略返回值类型
-
问题:函数返回标量(如
return 1
)会导致结果被压缩为 Series。 -
解决方案:确保返回值类型一致(如始终返回 Series 或 DataFrame)。
2. 分组键被错误保留
-
问题:
groupby.apply()
可能保留分组键作为索引。 -
解决方案:使用
as_index=False
或reset_index()
:Python复制
df.groupby('Name', as_index=False).apply(func)
六、实战项目:数据清洗与特征工程
案例 1:数据标准化
Python复制
# 对每列进行 Min-Max 标准化
def min_max_scale(col):
return (col - col.min()) / (col.max() - col.min())
df_scaled = df.apply(min_max_scale)
案例 2:文本处理
Python复制
# 将文本列转换为长度
df['Text_Length'] = df['Text'].apply(len)
案例 3:特征衍生
Python复制
# 根据年龄列生成年龄段
def age_group(age):
if age < 18:
return 'Minor'
elif 18 <= age <= 65:
return 'Adult'
else:
return 'Senior'
df['Age_Group'] = df['Age'].apply(age_group)
七、总结
-
核心价值:
apply()
的灵活性使其成为处理复杂逻辑的首选工具。 -
最佳实践:优先使用向量化操作,仅在必要时使用
apply()
。 -
进阶方向:结合
lambda
、自定义函数和分组操作,解决真实业务问题。
通过本文的学习,你应该能熟练使用 apply()
处理数据清洗、特征工程、分组统计等任务。如果遇到性能瓶颈,记得尝试用向量化操作或内置函数替代!