You need to enable JavaScript to run this app. Pandas 1.1.3版本多级索引DataFrame unstack后fillna方法失效问题
优惠活动
大模型
产品
解决方案
定价
更多

Pandas 1.1.3版本多级索引DataFrame unstack后fillna方法失效问题

多级索引DataFrame unstack后fillna填充失效问题

问题复现场景

构造测试数据

执行如下代码,生成包含部分缺失值的多级索引DataFrame:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randint(0,10,(5,4)),
                 columns=['c1','c2','c3','c4'])
df.iloc[1,2] = np.nan
df.iloc[0,0] = np.nan
df['ind1'] = ['a','a','b','b','c']
df['ind2'] = [1,2,1,2,1]
df = df.set_index(['ind1','ind2'])
print(df)

输出的DataFrame结构为:

c1  c2   c3  c4
ind1 ind2                  
a    1     NaN   2  1.0   9
     2     9.0   5  NaN   7
b    1     1.0   7  2.0   8
     2     3.0   6  0.0   2
c    1     9.0   6  6.0   6

异常行为触发

对unstack后的DataFrame执行fillna(0)操作,会出现部分缺失值未被成功替换的问题,输出结果为:

c1        c2        c3        c4     
ind2    1    2    1    2    1    2    1    2
ind1                                        
a     0.0  9.0  2.0  5.0  1.0  0.0  9.0  7.0
b     1.0  3.0  7.0  6.0  2.0  0.0  8.0  2.0
c     9.0  0.0  6.0  NaN  6.0  0.0  6.0  NaN

问题属性判定

  • 该现象不属于pandas的版本设计预期行为,是pandas 1.1.3版本的已知缺陷
  • 缺陷触发逻辑:unstack操作生成二级列索引结构时,因索引维度不完整产生的NaN值,在后续fillna的索引对齐环节出现匹配偏差,导致部分位置的NaN无法被识别替换
  • 该缺陷已在后续版本修复,升级至pandas 1.2.1版本后,同类操作可正常完成全量缺失值填充,无上述异常

临时解决方案

原有实现方式

通过np.nan_to_num处理底层数组后重构DataFrame,可实现全量缺失值填充为0的效果,对应代码为:

df2 = df.unstack()
df2 = pd.DataFrame(np.nan_to_num(df2.values), index=df2.index, columns=df2.columns)
print(df2)

运行后可得到正确的填充结果:

c1        c2        c3        c4     
ind2    1    2    1    2    1    2    1    2
ind1                                        
a     0.0  9.0  2.0  5.0  1.0  0.0  9.0  7.0
b     1.0  3.0  7.0  6.0  2.0  0.0  8.0  2.0
c     9.0  0.0  6.0  0.0  6.0  0.0  6.0  0.0

简化写法

可省去新建DataFrame的冗余步骤,直接对DataFrame的底层数值矩阵赋值替换,代码更简洁:

df2 = df.unstack()
df2.values[:] = np.nan_to_num(df2.values)

内容的提问来源于stack exchange,提问作者Seung Hyeon Yu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 11:54:03