结合groupby与mean使用时fillna失效问题的排查与解决
问题分析与解决方案
嘿,我来帮你捋清楚这个问题哈!你遇到的“只有第一个NaN被填充”的情况,核心是索引不匹配导致的,咱们一步步拆解:
为什么只有第一个NaN被填充?
你原来的填充代码里,df2.groupby('Country Name', as_index=False)['CO2'].mean()['CO2'] 返回的是一个只包含各国均值的Series,但这个Series的索引是分组后的新序列(比如0、1、2...),和原DataFrame df2 里Zambia行的索引(262、526、790这些)完全对不上。
当Pandas执行fillna时,它会尝试把均值Series里的值按索引一一对应填充到原DataFrame中。你的例子里刚好有一行的索引和均值Series的某个索引匹配,所以只有那一行的NaN被填上了,其他行因为找不到对应索引的均值,NaN就保留下来了。
正确实现:用transform批量填充各国均值
要让每个国家的NaN都用上自己国家的CO2均值填充,用groupby+transform是最直接的方案。transform的作用就是把分组计算出来的结果(比如均值)“广播”到该组的每一行,这样每一行都能拿到对应国家的均值,索引完全匹配,填充就不会出错了。
修改后的代码如下:
# 计算每个国家的CO2均值,并广播到组内每一行 country_co2_mean = df2.groupby('Country Name')['CO2'].transform('mean') # 用对应国家的均值填充NaN df2['CO2'] = df2['CO2'].fillna(country_co2_mean)
测试你的Zambia数据
执行完上面的代码后,你的Zambia数据会变成这样:
| Country Name | Year | CO2 |
|---|---|---|
| Zambia | 1960 | 0.484002 |
| Zambia | 1961 | 0.484002 |
| Zambia | 1962 | 0.484002 |
| Zambia | 1963 | 0.484002 |
| Zambia | 1964 | 0.949422 |
所有Zambia的NaN都被正确填充成了该国的CO2均值,完美解决问题~
紧凑写法
如果觉得单独定义变量麻烦,也可以把代码合并成一行:
df2['CO2'] = df2['CO2'].fillna(df2.groupby('Country Name')['CO2'].transform('mean'))
效果完全一样,代码更简洁。
内容的提问来源于stack exchange,提问作者cal17_hogo
相关产品推荐
相关产品推荐

