Pandas列子集分组:用众数填充Tom的缺失值问题
解决分组填充缺失值的问题
原代码的问题
你的代码存在两个关键问题:
- 使用
inplace=True时,fillna会返回None,直接赋值给data['value']会把整列覆盖为空值 - 计算众数时用了整个数据集的
Value列,而非仅Tom子集的众数,不符合需求
针对Tom子集的正确实现
方式一:分步处理(直观易懂)
# 先计算Tom分组中Value的众数 tom_mode = data.loc[data["Name"] == 'Tom', 'Value'].mode()[0] # 仅对Tom的缺失Value进行填充 data.loc[data["Name"] == 'Tom', 'Value'] = data.loc[data["Name"] == 'Tom', 'Value'].fillna(tom_mode)
方式二:用groupby+transform简化代码
如果后续需要扩展到其他分组,这个写法更灵活:
# 对每个Name分组,用自身的众数填充缺失值 data['Value'] = data.groupby('Name')['Value'].transform(lambda x: x.fillna(x.mode()[0]))
要是只想针对Tom,加个条件过滤即可:
import pandas as pd data['Value'] = data.apply( lambda row: row['Value'] if row['Name'] != 'Tom' or pd.notna(row['Value']) else data.loc[data['Name'] == 'Tom', 'Value'].mode()[0], axis=1 )
处理多个目标分组(比如Tom和jack)
如果要给多个Name(如Tom、jack)分别用各自的众数填充,推荐用groupby结合筛选的方式:
# 指定需要处理的Name列表 target_names = ['Tom', 'jack'] # 筛选出目标行,按组填充 mask = data['Name'].isin(target_names) data.loc[mask, 'Value'] = data[mask].groupby('Name')['Value'].transform(lambda x: x.fillna(x.mode()[0]))
注意:如果某个分组的Value全是NaN(比如jack的情况),x.mode()[0]会报错,可以加兜底逻辑:
def fill_mode(x): mode_result = x.mode() # 全空时用0填充,可根据需求修改为其他值 return x.fillna(mode_result[0] if not mode_result.empty else 0) mask = data['Name'].isin(['Tom', 'jack']) data.loc[mask, 'Value'] = data[mask].groupby('Name')['Value'].transform(fill_mode)
最终效果
处理后Tom的两个NaN会被填充为20.0(Tom子集Value的众数),jack的NaN若用兜底逻辑会被填0,其他分组的缺失值保持不变。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

