如何按另一列分组,用众数填充Pandas DataFrame列的缺失值?
问题需求
需要在Pandas DataFrame的col_A列中,按col_B分组,用每组col_A的众数填充该列的缺失值。例如当col_A为缺失值且col_B=5时,填充该分组的众数1。已尝试手动生成分组对应关系DataFrame,但不知如何完成填充,求更简洁的实现方法。
示例数据
原始DataFrame
col_A col_B 8 31 7 30 20 83 NaN 5 8 31 9 34 37 158 ... ...
分组统计结果
col_A col_B 1 8 1 5 1 10 5 2 7 6 8 5 6 8 1 ... ... ...
尝试的代码
indx_lst=df.groupby(['Col_B','Col_A']).size().to_frame().index.to_list() A_list=[] B_list=[] for i in indx_lst: x,y=i[0],i[1] if x in B_list: pass else: B_list.append(x) A_list.append(y) A_col_null_imput=pd.DataFrame(np.column_stack([B_list,A_list]),columns=['B_most_freq','A_imputer'])
简洁实现方法
无需手动遍历生成映射关系,直接利用Pandas的分组聚合+映射填充即可完成,步骤如下:
核心代码
# 生成col_B分组对应的col_A众数映射(取第一个众数) mode_map = df.groupby('col_B')['col_A'].agg(lambda x: x.mode()[0]) # 用映射值填充col_A的缺失值 df['col_A'] = df['col_A'].fillna(df['col_B'].map(mode_map))
代码解释
groupby('col_B')['col_A'].agg(lambda x: x.mode()[0]):按col_B分组后,计算每个分组col_A的众数,mode()[0]确保每组返回单个值(若存在多个众数,默认取第一个)。df['col_B'].map(mode_map):将每行的col_B值匹配到对应的分组众数,生成与原DataFrame行数一致的填充序列。fillna:用上述序列替换col_A中的所有缺失值。
异常处理(可选)
如果存在某个col_B分组的col_A全为缺失值,x.mode()会返回空序列,此时mode()[0]会报错。可以提前计算全局众数作为兜底值:
# 计算col_A的全局众数 global_mode = df['col_A'].mode()[0] # 生成分组众数,空分组用全局众数填充 mode_map = df.groupby('col_B')['col_A'].agg( lambda x: x.mode()[0] if not x.mode().empty else global_mode ) df['col_A'] = df['col_A'].fillna(df['col_B'].map(mode_map))
内容的提问来源于stack exchange,提问作者Toni
相关产品推荐
相关产品推荐

