如何正确使用Pandas的.apply()实现DataFrame列的条件更新?
解决方案
第一步:提前计算df_1中各'a'值对应的'c'列中位数
先对df_1按'a'分组计算中位数,得到可快速查询的Series,避免在逐行处理时重复计算,提升效率:
# 生成index为a值、值为对应c列中位数的Series a_median_c = df_1.groupby('a')['c'].median()
第二步:编写逐行处理函数并正确调用apply
def set_c(row): # 判断当前行a值是否存在于预计算的中位数索引中 if row['a'] in a_median_c.index: # 若c值为0则替换为对应中位数,否则保留原c值 return a_median_c[row['a']] if row['c'] == 0 else row['c'] else: # a值不在df_1中,直接返回原c值 return row['c'] # 正确调用apply:传入函数对象,axis=1指定逐行处理 df_2['c'] = df_2.apply(set_c, axis=1)
你之前的问题原因
直接调用
df_2['c'] = set_c(df_1, df_2):
你的set_c函数应该是对整个DataFrame做了全局处理,没有逐行判断条件,导致返回单一值或全局替换结果,所有行被统一修改。使用
df_2.apply(set_c(df_2, df_1)):
apply需要传入函数对象,而你直接执行了set_c(df_2, df_1),把函数执行结果传给了apply,不符合语法要求。另外逐行处理时,函数默认接收的是每行的Series,无需传入整个DataFrame。
示例验证
假设测试数据如下:
import pandas as pd df_1 = pd.DataFrame({'a': [1,1,2,2], 'b': [10,20,30,40], 'c': [7,9,90,110]}) df_2 = pd.DataFrame({'a': [1,2,3], 'b': [100,200,300], 'c': [0,100,0]})
运行上述代码后,df_2的结果为:
| a | b | c |
|---|---|---|
| 1 | 100 | 8.0 |
| 2 | 200 | 100.0 |
| 3 | 300 | 0.0 |
完全符合你的期望结果。
内容的提问来源于stack exchange,提问作者newnewer
相关产品推荐
相关产品推荐

