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

Pandas右连接出现NaN索引与新增key列问题及正确实现方法

问题场景与疑问

用户创建两个DataFrame并执行右连接操作,代码如下:

import pandas as pd

df1 = pd.DataFrame({'key':[1,2,3], 'values':[11,22,33]})
# df1内容:
#    key values
# 0   1   11
# 1   2   22
# 2   3   33

df2 = pd.DataFrame({'key':[1,2,4],'values':[11,222,44]})
# df2内容:
#    key values
# 0   1   11
# 1   2   222
# 2   4   44

# 执行右连接
df12j3 = df1.join(df2, lsuffix='df1', rsuffix='df2', on='key', how='right')

实际得到的结果:

key    keydf1  valuesdf1   keydf2  valuesdf2
NaN   0    NaN       NaN           1    11
0.0   1    1.0      11.0           2    222
1.0   2    2.0      22.0           4    44

用户期望的结果:

keydf1  valuesdf1   keydf2  valuesdf2
0      1        11         1    11
1      2        22         2    222
2      NaN      NaN        4    44

用户提出两个疑问:

  • 为什么右连接结果中会生成新的key列并出现NaN索引?
  • 如何实现得到期望的连接结果?

问题解答

一、异常结果的原因

DataFrame.join()的on参数是指定左DataFrame的列或索引作为连接键,但右DataFrame不会自动同步把对应列设为索引。当使用how='right'时,结果的索引会直接沿用右DataFrame的原有索引,而左DataFrame中没有匹配右df里key=4的行,对应的左df索引就会显示NaN。

另外,那个多余的key列其实是右df原本的key列(因为它没被设为连接键,所以作为普通列保留了),而keydf1、keydf2是因为左右df都有key列,通过后缀区分后的列名。本质是用join的方式不对,把左df的列当连接键,但右df还是用自身索引参与连接,导致逻辑混乱,才出现了多余列和异常索引。

二、实现期望结果的方法

方法1:用merge()替代join()(推荐)

merge()是Pandas专门用于列与列之间连接的方法,更适合这种非索引列的连接场景:

# 基础右连接,得到接近期望的结果
df_result = df1.merge(df2, on='key', how='right', suffixes=('_df1', '_df2'))

# 调整列名和格式到完全匹配期望样式
df_result = df_result.rename(columns={
    'key': 'keydf2',
    'values_df1': 'valuesdf1',
    'values_df2': 'valuesdf2'
})
# 添加keydf1列,匹配成功的行和keydf2一致,无匹配的设为NaN
df_result['keydf1'] = df_result['keydf2']
df_result.loc[df_result['valuesdf1'].isna(), 'keydf1'] = pd.NA
# 调整列顺序
df_result = df_result[['keydf1', 'valuesdf1', 'keydf2', 'valuesdf2']].reset_index(drop=True)

执行后得到的结果就是用户期望的样式:

keydf1  valuesdf1  keydf2  valuesdf2
0      1       11.0       1         11
1      2       22.0       2        222
2    NaN        NaN       4         44

方法2:先设索引再用join()

如果一定要用join(),需要先把两个DataFrame的key列都设为索引,再执行连接:

# 将两个df的key列设为索引
df1_idx = df1.set_index('key')
df2_idx = df2.set_index('key')

# 执行右连接并重置索引
df_result = df1_idx.join(df2_idx, lsuffix='df1', rsuffix='df2', how='right').reset_index()

# 调整列名和格式
df_result = df_result.rename(columns={'key': 'keydf2'})
df_result['keydf1'] = df_result['keydf2']
df_result.loc[df_result['valuesdf1'].isna(), 'keydf1'] = pd.NA
df_result = df_result[['keydf1', 'valuesdf1', 'keydf2', 'valuesdf2']].reset_index(drop=True)

这种方式也能得到和期望一致的结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:32:33