【pandas】pandas apply 方法详解
【pandas】-1-读取数据
【pandas】-2-数据查询
【pandas】-3-Pandas 索引
【pandas】-4- 索新增列,assign,applay,map使用
【pandas】-5-缺失值处理
【pandas】-6-排序&去重
【pandas】-7-数据分组处理
【pandas】-8-数据变形/数据透视
【pandas】pandas中mask()方法的详细用法
pandas apply 方法详解
文章目录
- pandas apply 方法详解
- 基本语法
- DataFrame.apply()
- Series.apply()
- 参数说明
- 基本用法示例
- 1. 对 Series 应用函数
- 2. 对 DataFrame 按列应用函数
- 3. 对 DataFrame 按行应用函数
- 高级用法
- 4. 使用 args 参数传递额外参数
- 5. 使用 result_type 控制输出格式
- 6. 处理多个返回值的不同方式
- 7. 实际应用案例
- 性能考虑
- 8. 使用 raw=True 提高性能
- 9. 替代方案
- 总结
apply() 是 pandas 中非常强大和灵活的方法,用于对 DataFrame 或 Series 应用自定义函数。下面详细讲解其用法。
基本语法
DataFrame.apply()
DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwargs)
Series.apply()
Series.apply(func, convert_dtype=True, args=(), **kwargs)
参数说明
- func: 要应用的函数
- axis:
- 0 或 ‘index’: 对每列应用函数(默认)
- 1 或 ‘columns’: 对每行应用函数
- raw: 布尔值,决定传递的数据类型
- False: 将每行/列作为 Series 传递
- True: 将每行/列作为 ndarray 传递
- result_type: 仅当 axis=1 时有效
- ‘expand’: 将列表式结果转换为列
- ‘reduce’: 返回 Series(如果可能)
- ‘broadcast’: 将结果广播回原始形状
基本用法示例
1. 对 Series 应用函数
import pandas as pd
import numpy as np# 创建 Series
s = pd.Series([1, 2, 3, 4, 5])# 应用简单函数
result = s.apply(lambda x: x**2)
print(result)
# 输出: 0:1, 1:4, 2:9, 3:16, 4:25# 应用自定义函数
def custom_func(x):return x * 10 if x > 3 else xresult = s.apply(custom_func)
print(result)
2. 对 DataFrame 按列应用函数
# 创建 DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4],'B': [10, 20, 30, 40],'C': [100, 200, 300, 400]
})# 对每列求和(虽然可以直接用 df.sum())
result = df.apply(np.sum, axis=0)
print(result)
# 输出: A:10, B:100, C:1000# 对每列应用自定义函数
def column_stats(col):return f"mean:{col.mean():.2f}, std:{col.std():.2f}"result = df.apply(column_stats)
print(result)
3. 对 DataFrame 按行应用函数
# 对每行求和
result = df.apply(np.sum, axis=1)
print(result)
# 输出: 0:111, 1:222, 2:333, 3:444# 对每行应用复杂函数
def row_operation(row):return row['A'] * row['B'] + row['C']result = df.apply(row_operation, axis=1)
print(result)
高级用法
4. 使用 args 参数传递额外参数
def weighted_sum(row, weights):return sum(row * weights)weights = [0.5, 0.3, 0.2]
result = df.apply(weighted_sum, axis=1, args=(weights,))
print(result)
5. 使用 result_type 控制输出格式
# 返回多列结果
def expand_func(row):return pd.Series({'sum': row.sum(),'mean': row.mean(),'max': row.max()})# 使用 expand 将结果扩展为多列
result = df.apply(expand_func, axis=1, result_type='expand')
print(result)
6. 处理多个返回值的不同方式
# 返回列表
def return_list(row):return [row.min(), row.max(), row.mean()]# 不同 result_type 的效果
result1 = df.apply(return_list, axis=1) # 返回 Series of lists
result2 = df.apply(return_list, axis=1, result_type='expand') # 扩展为 DataFrame
result3 = df.apply(return_list, axis=1, result_type='broadcast') # 广播回原形状print("原始 result_type:")
print(result1.head())
print("\n使用 expand:")
print(result2.head())
7. 实际应用案例
# 数据清洗示例
df_data = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David'],'age': [25, 30, 35, 40],'salary': ['$50,000', '$60,000', '$70,000', '$80,000'],'email': ['alice@email.com', 'bob@email.com', 'charlie', 'david@email.com']
})# 清洗薪资数据
def clean_salary(sal):if isinstance(sal, str):return int(sal.replace('$', '').replace(',', ''))return sal# 验证邮箱格式
def validate_email(email):import repattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'return bool(re.match(pattern, email))# 应用清洗函数
df_data['salary_clean'] = df_data['salary'].apply(clean_salary)
df_data['email_valid'] = df_data['email'].apply(validate_email)print(df_data)
性能考虑
8. 使用 raw=True 提高性能
# 对于数值运算,使用 raw=True 可以提高性能
def simple_operation(x):return x * 2 + 1# 比较性能
%timeit df.apply(simple_operation, axis=1) # 较慢
%timeit df.apply(simple_operation, axis=1, raw=True) # 较快
9. 替代方案
对于简单操作,考虑使用向量化操作代替 apply:
# 使用 apply(较慢)
result_slow = df.apply(lambda row: row['A'] * 2 + row['B'], axis=1)# 使用向量化操作(较快)
result_fast = df['A'] * 2 + df['B']# 验证结果相同
print(result_slow.equals(result_fast)) # 输出: True
总结
- 灵活性: apply() 可以应用任何自定义函数
- 方向控制: 通过 axis 参数控制按行或按列应用
- 输出控制: 使用 result_type 控制返回数据的格式
- 性能优化: 对于数值运算,考虑使用 raw=True
- 替代方案: 对于简单操作,优先使用向量化操作
apply() 是 pandas 中非常强大的工具,但在大数据集上使用时需要注意性能问题,尽量使用向量化操作或考虑其他优化方法。
