如何将行作为参数,实现Pandas DataFrame通用列填充函数?
解决泛化列填充函数的问题
你的思路是对的,但在apply的调用方式上出了问题——直接调用add(...)会导致Python尝试立刻执行这个函数,而此时row参数还没被传入(apply是遍历行的时候才会传row),所以会触发语法和参数错误。下面给你几种可行的修改方案,包括更高效的矢量化实现:
方案1:用Lambda包装参数调用
这是最直接的修改方式,用lambda函数把列名参数传递给你的add函数,让apply在遍历每一行时自动传入row:
import pandas as pd def add(row, new_column, old_column): if pd.notnull(row[new_column]): return row else: row[new_column] = row[old_column] return row # 注意:列名如果是字符串要加引号,比如'industry'和'old_industry' merged2 = merged2.apply(lambda row: add(row, 'industry', 'old_industry'), axis=1)
方案2:用functools.partial绑定参数
如果需要多次复用这个函数(比如填充不同的列对),用partial来预先绑定列名参数会更优雅:
import pandas as pd from functools import partial def add(row, new_column, old_column): if pd.notnull(row[new_column]): return row else: row[new_column] = row[old_column] return row # 预先绑定要填充的列对 fill_industry = partial(add, new_column='industry', old_column='old_industry') # 执行填充 merged2 = merged2.apply(fill_industry, axis=1)
方案3:用Pandas矢量化操作(推荐)
逐行apply在大数据集上效率很低,Pandas内置的fillna方法可以直接实现这个需求,而且性能好很多:
# 直接将new_column的空值用old_column对应位置的值填充 merged2['industry'] = merged2['industry'].fillna(merged2['old_industry'])
关键说明:
- 你原来的
add(, industry, old_industry)有两个问题:一是语法错误(第一个参数为空),二是apply需要接收函数对象,而不是函数执行后的结果。lambda和partial的作用就是帮我们把列名参数预先绑定,让函数在apply遍历行时能正确接收row参数。 - 列名要确保是字符串类型,如果是用变量存储列名,要保证变量值是DataFrame中存在的列名。
内容的提问来源于stack exchange,提问作者kaecvtionr
相关产品推荐
相关产品推荐

