You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas多索引下pd.concat处理pd.NA的异常问题咨询

关于Pandas 1.4.2多索引DataFrame拼接异常问题的解答

问题一:横向拼接含(pd.NA, pd.NA)多索引DataFrame的异常

疑问点

  • 既然pd.NA彼此不相等,为何pd.concat会将两个DataFrame中(pd.NA, pd.NA)行的内容合并到同一行?
  • 输入中存在的(NaN, 3.0)行为何在输出中消失?拼接应保留所有输入索引行。

示例代码与结果

构造第一个DataFrame:

import pandas as pd

test_B = pd.DataFrame(
    [19,18,17,16,15,14, 13, pd.NA],
    columns=['predictionB'],
    index=pd.MultiIndex.from_tuples(
        [(1.0, 1.0),(2.0, 1.0), (2.0, 2.0), (2.0, pd.NA), (3.0, 1.0),(4.0, 1.0),(4.0, 2.0),(pd.NA, pd.NA)],
        names=["first", "second"]
    )
)

test_B输出:

predictionB
first second            
1.0   1.0             19
2.0   1.0             18
      2.0             17
      NaN             16
3.0   1.0             15
4.0   1.0             14
      2.0             13
NaN   NaN           <NA>

构造第二个DataFrame:

test_Z = pd.DataFrame(
    [pd.NA,18,17,16,15,14, 13, 9, 11],
    columns=['predictionZ'],
    index=pd.MultiIndex.from_tuples(
        [(1.0, pd.NA),(2.0, pd.NA), (2.0, 2.0), (2.0, 3.0), (3.0, 1.0),(4.0, 1.0),(4.0, 2.0),(pd.NA, pd.NA), (pd.NA, 3.0)],
        names=["first", "second"]
    )
)

test_Z输出:

predictionZ
first second            
1.0   NaN           <NA>
2.0   NaN             18
      2.0             17
      3.0             16
3.0   1.0             15
4.0   1.0             14
      2.0             13
NaN   NaN              9
      3.0             11

执行拼接并排序索引:

pd.concat([test_B, test_Z], axis=1).sort_index()

得到结果:

predictionB predictionZ
first second                        
1.0   1.0             19         NaN
      NaN            NaN        <NA>
2.0   1.0             18         NaN
      2.0             17          17
      NaN             16          18
3.0   1.0             15          15
4.0   1.0             14          14
      2.0             13          13
NaN   NaN           <NA>           9

问题一解答

  1. (pd.NA, pd.NA)行合并的原因:
    Pandas索引对齐逻辑中,多索引的匹配以哈希键为依据。尽管pd.NA == pd.NA返回pd.NA,但Pandas索引系统会将pd.NA(包括np.nan)视为等价匹配键——这是为了在缺失值场景下仍能完成索引对齐,避免因缺失值无法匹配导致的索引数量异常增长。因此两个DataFrame中的(pd.NA, pd.NA)会被识别为同一索引项,内容合并到同一行。

  2. (NaN, 3.0)行消失的原因:
    这是Pandas 1.4.2版本的已知Bug。当多索引中存在外层为pd.NA、内层为非缺失值的索引项(如(pd.NA, 3.0))时,sort_index()会错误地过滤或隐藏该索引项。该问题在Pandas 1.5.0及以上版本已修复。临时解决方案:可以先查看未排序的拼接结果(去掉.sort_index()),或直接升级Pandas版本。


问题二:groupby生成的含pd.NA多索引DataFrame拼接出现重复行

拼接由groupby生成的、多索引含pd.NA的DataFrame时,(pd.NA, pd.NA)行出现重复且内容完全相同。将pd.NA替换为字符串后问题消失,请问重复行产生的原因是什么?

示例代码与结果

uuu_1(groupby生成的Series):

one  two
4.0  3.0    22
     4.0    44
NaN  1.0    14
     2.0     2
     4.0     6
     NaN    15
Name: providerA, dtype: int64

uuu_2(groupby生成的Series):

one  two
3.0  3.0     30
     4.0     53
4.0  2.0      8
     3.0     20
     4.0     99
NaN  NaN     12
Name: providerB, dtype: int64

执行拼接并排序索引:

pd.concat([uuu_1, uuu_2], axis=1).sort_index()

得到结果:

providerA  providerB
one two                       
3.0 3.0        NaN       30.0
    4.0        NaN       53.0
4.0 2.0        NaN        8.0
    3.0       22.0       20.0
    4.0       44.0       99.0
NaN 1.0       14.0        NaN
    2.0        2.0        NaN
    4.0        6.0        NaN
    NaN       15.0       12.0
    NaN       15.0       12.0

问题二解答

重复行的根源是Pandas 1.4.2版本中,groupby生成多索引时对pd.NA的哈希处理逻辑存在缺陷。当groupby结果包含(pd.NA, pd.NA)索引项时,内部会为该索引生成重复的哈希标识,导致pd.concat对齐时将其判定为两个不同的索引项,但实际显示的索引值完全一致。

将pd.NA替换为字符串后,字符串的哈希值唯一且稳定,不会出现重复标识问题,因此重复行消失。升级到Pandas 1.5.0及以上版本可彻底解决该问题。


内容的提问来源于stack exchange,提问作者Stephane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:01:46