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

Pandas 2.1.3多索引Join为何意外匹配NaN值?

Pandas多索引join匹配NaN的问题分析

问题描述

使用Pandas 2.1.3版本,尝试基于多索引的部分级别连接两个DataFrame,其中一个DataFrame的索引包含NaN值,得到的连接结果与预期不符。

复现代码

import pandas as pd
import numpy as np

a = pd.DataFrame({
    'idx_a':['A', 'A', 'B'],
    'idx_b':['alpha', 'beta', 'gamma'],
    'idx_c': [1.0, 1.0, 1.0],
    'x':[10, 20, 30]
}).set_index(['idx_a', 'idx_b', 'idx_c'])

b = pd.DataFrame({
    'idx_b':['gamma', 'delta', 'epsilon', np.nan, np.nan],
    'idx_c': [1.0, 1.0, 1.0, 1.0, 1.0],
    'y':[100, 200, 300, 400, 500]
}).set_index(['idx_b', 'idx_c'])

# 执行连接
c = a.join(
    b,
    how='inner',
    on=['idx_b', 'idx_c']
)

print("DataFrame a:")
print(a)
print("\nDataFrame b:")
print(b)
print("\n实际连接结果:")
print(c)

实际输出

DataFrame a:
                    x
idx_a idx_b idx_c    
A     alpha 1.0    10
      beta  1.0    20
B     gamma 1.0    30

DataFrame b:
                y
idx_b   idx_c     
gamma   1.0    100
delta   1.0    200
epsilon 1.0    300
NaN     1.0    400
        1.0    500

实际连接结果:
                    x    y
idx_a idx_b idx_c         
B     gamma 1.0    30  100
            1.0    30  400
            1.0    30  500

预期结果

x    y
idx_a idx_b idx_c         
B     gamma 1.0    30  100

疑问

为什么join会将非NaN的idx_b='gamma'与idx_b=NaN的行匹配?


原因分析

这是Pandas 2.1.3版本中join方法处理多索引与指定连接键时的异常行为:当使用on参数指定多索引的部分列作为连接键,且另一个DataFrame的索引包含NaN时,内部匹配逻辑出现偏差——错误地仅以idx_c的匹配为依据,忽略了idx_b中非NaN与NaN的不相等性,进而对符合idx_c匹配条件的行执行了笛卡尔积连接。

正常情况下,Pandas的连接操作应该要求所有指定的连接键完全匹配才会合并行,NaN与任何非NaN值都不应被视为相等。但在该场景下,join的多索引对齐逻辑出现了错误。


解决方法

方法1:改用merge方法

通过重置索引为普通列,明确指定连接键执行合并,再重新设置索引:

c = pd.merge(a.reset_index(), b.reset_index(), on=['idx_b', 'idx_c'], how='inner').set_index(['idx_a', 'idx_b', 'idx_c'])
print(c)

方法2:过滤NaN索引行

先过滤掉b中包含NaN的索引行,再执行join:

# 过滤idx_b为NaN的行
b_filtered = b[b.index.get_level_values('idx_b').notna()]
c = a.join(b_filtered, how='inner', on=['idx_b', 'idx_c'])
print(c)

两种方法都能得到预期的正确结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:27:32