如何为pandas DataFrame的每行应用不同的可调用对象?
问题描述
我有三个行数相同的DataFrame:
input_df:存储输入数据param_df:存储计算参数,其中一列包含每行需要应用的可调用函数output_df:存储输出数据
以下是最小可复现代码(MWE),其中前5行需应用func_1,后5行应用func_2。我想摆脱笨拙的列表推导,改用map或apply实现逐行调用对应的可调用对象。
import pandas as pd import numpy as np def func_1(in_val, a, b): return in_val + a + b def func_2(in_val, a, b): return in_val + (2 * (a + b)) input_df = pd.DataFrame(data=[1 for row in range(10)], columns=["GR"]) output_df = pd.DataFrame(data=[np.nan for row in range(10)], columns=["VCLGR"]) param_df = pd.DataFrame(data=[[5, 10] for row in range(10)], columns=["x", "y"]) # 为每行指定对应的调用函数 param_df["method"] = func_1 param_df.loc[5:, "method"] = func_2 # 当前使用的列表推导方式 output_df["VCLGR"] = [param_df["method"][i](input_df["GR"][i], param_df["x"][i], param_df["y"][i]) for i in range(len(input_df))]
解决方案
方法1:使用pandas.DataFrame.apply(推荐,贴合pandas风格)
将input_df和param_df合并后,通过apply逐行调用对应函数:
# 合并输入数据与参数表(行数相同,按列拼接) combined_df = pd.concat([input_df, param_df], axis=1) # 逐行应用函数 output_df["VCLGR"] = combined_df.apply( lambda row: row["method"](row["GR"], row["x"], row["y"]), axis=1 # 指定按行处理 )
方法2:使用Python内置map函数
利用map可接收多个可迭代对象的特性,将函数列、输入值列、参数列打包后批量调用:
output_df["VCLGR"] = list(map( lambda func, gr_val, x_val, y_val: func(gr_val, x_val, y_val), param_df["method"], input_df["GR"], param_df["x"], param_df["y"] ))
说明
两种方法都避免了手动索引i的繁琐,代码更简洁易读:
apply是pandas原生的逐行处理方式,适合习惯pandas API的场景;map是Python函数式编程工具,执行效率略高(尤其是数据量较大时),但返回的是迭代器,需要用list转换为序列后赋值给DataFrame列。
内容的提问来源于stack exchange,提问作者dg0802
相关产品推荐
相关产品推荐

