Pandas多级索引DataFrame中df.fillna(df.mean())失效问题求助
Hey,我来帮你拆解下为啥df.fillna(df.mean())没把NaN都搞定,大概率是下面几个原因之一,对应解决办法我也列出来了:
可能的原因 & 解决方案
1. 你的DataFrame包含非数值型列
df.mean()只认数值型列(int/float类型),对于字符串、object、datetime这类非数值列,它直接返回NaN——用NaN去填充NaN,当然等于没处理,这些列的NaN自然还留在那里。
举个例子:如果你的df里有一列是用户的性别(字符串类型),这列的NaN根本没法用均值填充,因为字符串没有“均值”这个概念。
解决办法:
- 只针对数值型列做均值填充:
# 先筛选出所有数值型列 numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns # 只对这些列填充均值 df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean()) - 如果非数值列也需要处理,可以单独用众数填充(最常见的值):
# 数值列用均值,非数值列用众数 df = df.fillna(df.mean(numeric_only=True)).fillna(df.mode().iloc[0])
2. 某些列本身全是NaN
如果某一列的所有值都是NaN,那df.mean()计算这列的结果也是NaN——总不能用NaN去填充NaN吧?所以这类列的NaN会原封不动保留。
解决办法:
- 先排查哪些列全是NaN:
print(df.isna().all()) - 处理方式二选一:
# 方式1:直接删除全NaN的列(如果这些列没用的话) df = df.dropna(axis=1, how='all') # 方式2:用自定义值填充,比如0或者其他业务逻辑允许的默认值 df = df.fillna(df.mean()).fillna(0)
3. 数据范围的操作逻辑可能有问题
看你的代码是df = df.fillna(df.mean()).head(20),这里是先对整个DataFrame填充均值,再取前20行。但如果前20行里的某些列,在整个df中的均值本身就是NaN(比如整个df里这列几乎全是NaN),那填充后还是会有NaN。
另外,如果你的需求是只处理前20行的NaN,那你的代码逻辑反了——应该先取前20行,再针对这20行计算均值填充:
# 先取出前20行并复制(避免修改原df) df_head = df.head(20).copy() # 对这20行的数值列填充它们自己的均值 numeric_cols = df_head.select_dtypes(include=['int64', 'float64']).columns df_head[numeric_cols] = df_head[numeric_cols].fillna(df_head[numeric_cols].mean())
内容的提问来源于stack exchange,提问作者boure Li
相关产品推荐
相关产品推荐

