我正在使用Pandas 2.1.3.

我正在try 连接多个索引级别上的两个DataFrame,其中一个索引级别具有NA.最小的可重现示例如下:

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(a)
                    x
idx_a idx_b idx_c    
A     alpha 1.0    10
      beta  1.0    20
B     gamma 1.0    30

print(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

print(c)
                    x    y
idx_a idx_b idx_c         
B     gamma 1.0    30  100
            1.0    30  400
            1.0    30  500

我本以为会是:

print(c)
                    x    y
idx_a idx_b idx_c         
B     gamma 1.0    30  100

为什么join与这NaN个值匹配?

推荐答案

您可以通过删除索引并使用merge而不是join来解决问题:

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]
})

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]
})

c = a.merge(b, on=['idx_b', 'idx_c'], how='inner')

输出:

  idx_a  idx_b  idx_c   x    y
0     B  gamma    1.0  30  100

如果您想要保持ab上的索引不变,您可以这样做(谢谢@mozway):

c = (a
    .reset_index()
    .merge(b.reset_index(), on=['idx_b', 'idx_c'], how='inner')
    .set_index(list(dict.fromkeys(a.index.names+b.index.names)))
)

输出:

                    x    y
idx_a idx_b idx_c
B     gamma 1.0    30  100

Python相关问答推荐

如何将Pydantic URL验证限制为特定主机或网站

除了Python之外,可以替代bare?

在两极中实施频率编码

如何在vercel中指定Python运行时版本?

当值是一个integer时,在Python中使用JMESPath来验证字典中的值(例如:1)

请从Python访问kivy子部件的功能需要帮助

如何让我的Tkinter应用程序适合整个窗口,无论大小如何?

LAB中的增强数组

比较两个数据帧并并排附加结果(获取性能警告)

DataFrame groupby函数从列返回数组而不是值

Python json.转储包含一些UTF-8字符的二元组,要么失败,要么转换它们.我希望编码字符按原样保留

更改键盘按钮进入'

Polars asof在下一个可用日期加入

try 检索blob名称列表时出现错误填充错误""

dask无groupby(ddf. agg([min,max])?''''

(Python/Pandas)基于列中非缺失值的子集DataFrame

找到相对于列表索引的当前最大值列表""

在Admin中显示从ManyToMany通过模型的筛选结果

基于Scipy插值法的三次样条系数

干燥化与列姆化的比较