pandas groupby配合fillna按分组均值填充报错或不生效问题
问题原因
三种写法失效/报错的核心原因都和pandas索引对齐逻辑、版本兼容bug有关,具体对应:
- 第一种写法(loc+transform赋值)报错:pandas 1.x部分早期版本存在类型校验bug,当使用loc布尔切片给列赋值时,会错误校验等号右侧transform返回序列的dtype,将float64类型的均值误识别为long类型,和切片的对象类型标记不匹配,最终抛出
Buffer dtype mismatch错误,和列本身的实际数据类型无关。 - 第二种写法(直接用groupby均值fillna)填充失败:
df.groupby(["name", "job"])['weight'].mean()返回的是以name、job为多重索引的聚合结果,索引结构和原weight列的默认整数RangeIndex完全不匹配。fillna是按索引精确匹配填充值的,索引对不上时所有空值位置都找不到对应填充值,NaN自然会保留。 - 第三种写法(groupby+apply填充)填充失败:设置
sort=False时,部分pandas版本的groupby.apply会按分组键重排返回结果的索引,不会保留原表的行顺序,直接赋值回原列时会出现值行错位,无法正确匹配到空值位置完成填充。
正确实现方案
核心原则是保证待填充的均值序列和原weight列长度一致、索引完全对齐,最稳妥无兼容问题的写法是直接用transform返回对齐的分组均值,传入fillna即可,不需要做loc切片:
import pandas as pd # 构造测试数据 data = {'name': ['Alex', 'Ben', 'Marry','Alex', 'Ben', 'Marry'], 'job': ['teacher', 'doctor', 'engineer','teacher', 'doctor', 'engineer'], 'age': [27, 32, 78,27, 32, 78], 'weight': [160, 209, 130,164, 206, 132], 'date': ['6-12-2022', '6-12-2022', '6-12-2022','6-13-2022', '6-13-2022', '6-13-2022'] } df = pd.DataFrame(data) # 新增6-14的空值记录 df = pd.concat([df, pd.DataFrame({ 'name':['Alex','Ben','Marry'], 'job':['teacher','doctor','engineer'], 'age':[None,None,None], 'weight':[None,None,None], 'date':['6-14-2022']*3 })], ignore_index=True) # 正确分组填充weight列 df['weight'] = df['weight'].fillna( df.groupby(["name", "job"])['weight'].transform('mean') ) # 如需填充age列逻辑完全一致 df['age'] = df['age'].fillna( df.groupby(["name", "job"])['age'].transform('mean') )
运行后6-14的三条记录会被正确填充:
- Alex(teacher)的weight为162、age为27
- Ben(doctor)的weight为207.5、age为32
- Marry(engineer)的weight为131、age为78
内容的提问来源于stack exchange,提问作者mnm
相关产品推荐
相关产品推荐

