如何为DataFrame多列批量应用函数并自动生成对应新列
批量生成DataFrame新列的Pythonic实现需求
示例场景
现有如下DataFrame:
| Dogs | Cats | Horses |
|---|---|---|
| "Bobby" | "Memphis" | "Incitatus" |
| "Rudolph" | "Django" | "Rocinante" |
需求说明
需要实现一个函数,接收上述DataFrame和一个列表,对每个原列应用自定义函数my_function,自动生成命名规则为{原列名}_new的新列(如Dogs_new、Cats_new),最终返回扩展后的DataFrame。
自定义函数伪代码如下:
def my_function(name, list_of_names): if name in list_of_names: # 执行指定操作并返回结果 return something else: # 执行其他操作并返回结果 return something_else
尝试过的方法及问题
- 循环列名结合
apply的方式:无法在lambda中动态绑定当前列名,且写法不够简洁:
def main_function(dataframe, list_of_names): colnames = list(dataframe) for col in colnames: new_name = f"{col}_new" dataframe[new_name] = dataframe.apply(lambda x: my_function(x."original colname", list_of_names), axis=1) return dataframe
- 手动逐个添加新列:仅适用于少量列,无法处理大规模列的场景:
df["Dogs_new"] = df.apply(lambda x: my_function(x.Dogs, list_of_names), axis=1) df["Cats_new"] = df.apply(lambda x: my_function(x.Cats, list_of_names), axis=1) df["Horses_new"] = df.apply(lambda x: my_function(x.Horses, list_of_names), axis=1)
解决方案
方案1:修复循环+apply的绑定问题
解决lambda延迟绑定问题,通过默认参数绑定当前列名,实现动态列的处理:
def main_function(dataframe, list_of_names): for col in dataframe.columns: new_col_name = f"{col}_new" # 使用默认参数col=col绑定当前循环的列名,避免lambda引用最后一个列 dataframe[new_col_name] = dataframe.apply(lambda x, col=col: my_function(x[col], list_of_names), axis=1) return dataframe
方案2:批量处理(更Pythonic)
直接对整个DataFrame批量生成新列,统一重命名后合并,性能更优:
def main_function(dataframe, list_of_names): # 对每一列应用my_function,生成所有新列 new_columns = dataframe.apply(lambda col: col.apply(lambda val: my_function(val, list_of_names))) # 给新列添加后缀并合并到原DataFrame return dataframe.join(new_columns.add_suffix("_new"))
方案3:元素级批量处理(最优性能)
如果my_function仅作用于单个元素(不需要整行数据),使用applymap实现元素级批量处理,速度最快:
def main_function(dataframe, list_of_names): new_columns = dataframe.applymap(lambda val: my_function(val, list_of_names)).add_suffix("_new") return dataframe.join(new_columns)
说明
- 方案1适合需要访问整行数据的场景(如果后续
my_function需要用到其他列的值); - 方案2和3更适合纯列/元素级操作,写法简洁且性能优于逐行
apply; - 优先选择方案3,因为
applymap是元素级操作,比逐行apply的效率高很多。
内容的提问来源于stack exchange,提问作者maynouf
相关产品推荐
相关产品推荐

