基于条件在Pandas中跨DataFrame填充缺失值
Pandas 按规则跨DataFrame填充缺失值(可复用方法)
需求说明
我有两个索引不同的DataFrame(df1和df2),df1由第三个DataFrame经groupby聚合计算得到。需要按以下规则将df1的值填充到df2中,且方法需支持多列复用:
- 若df2目标列(如data1)行值为null/na:先按
name匹配df1,填充df1的avg2(groupby name)值; - 若匹配到的df1.avg2值也为null:再按
set匹配df1,填充df1的avg3(groupby set)值; - 其余情况填充
0.000。
输入示例
import pandas as pd import numpy as np # 聚合得到的df1 df1 = pd.DataFrame({ 'name_set': ['aa_001','bb_002','cc_003','aa_002','aa_001','cc_002'], 'name': ['aa','bb','cc','aa','aa','cc'], 'set': ['001','002','003','002','001','002'], 'avg1(groupby name_set)': [2,3,np.nan,1,2,np.nan], 'avg2(groupby name)': [3,2,np.nan,3,3,1], 'avg3(groupby set)': [2,3,1,3,2,3] }) # 需要填充的df2 df2 = pd.DataFrame({ 'name_set': ['aa_001','bb_002','cc_003','aa_002','aa_001','cc_002'], 'name': ['aa','bb','cc','aa','aa','cc'], 'set': ['001','002','003','002','001','002'], 'data1': [2,3,np.nan,1,2,np.nan] })
预期输出
# 填充后的df2 filled_df2 = pd.DataFrame({ 'name_set': ['aa_001','bb_002','cc_003','aa_002','aa_001','cc_002'], 'name': ['aa','bb','cc','aa','aa','cc'], 'set': ['001','002','003','002','001','002'], 'data1': [2,3,1,1,2,1] })
解决方案
思路解析
- 先从df1中提取
name与avg2、set与avg3的唯一映射关系(因为groupby聚合后,同一name/set对应的avg值应该一致); - 编写通用填充函数,按规则依次填充缺失值,最后处理剩余空值;
- 函数支持多列复用,只需传入不同目标列名即可。
代码实现
1. 编写可复用填充函数
def fill_missing_values(df_target, df_source, target_col, name_col='name', set_col='set', avg2_col='avg2(groupby name)', avg3_col='avg3(groupby set)'): # 提取name到avg2的唯一映射 name_avg2_map = df_source.drop_duplicates(name_col)\ .set_index(name_col)[avg2_col]\ .to_dict() # 提取set到avg3的唯一映射 set_avg3_map = df_source.drop_duplicates(set_col)\ .set_index(set_col)[avg3_col]\ .to_dict() # 复制目标列,避免修改原DataFrame filled_col = df_target[target_col].copy() # 第一步:填充目标列空值为对应name的avg2 mask_null = filled_col.isna() filled_col.loc[mask_null] = df_target.loc[mask_null, name_col].map(name_avg2_map) # 第二步:填充第一步后仍为空的值为对应set的avg3 mask_still_null = filled_col.isna() filled_col.loc[mask_still_null] = df_target.loc[mask_still_null, set_col].map(set_avg3_map) # 第三步:剩余空值填充0.000 filled_col = filled_col.fillna(0.000) return filled_col
2. 调用函数填充目标列
# 填充df2的data1列 df2['data1'] = fill_missing_values(df2, df1, 'data1') # 查看结果 print(df2)
3. 多列复用示例
如果df2还有data2、data3需要按相同规则填充,直接重复调用函数即可:
# 填充data2列 df2['data2'] = fill_missing_values(df2, df1, 'data2') # 填充data3列 df2['data3'] = fill_missing_values(df2, df1, 'data3')
内容的提问来源于stack exchange,提问作者Reshma Ahmed
相关产品推荐
相关产品推荐

