Pandas 通过两列左连接 DataFrames

Posted

技术标签:

【中文标题】Pandas 通过两列左连接 DataFrames【英文标题】:Pandas left join DataFrames by two columns 【发布时间】:2018-11-26 02:39:20 【问题描述】:

您能帮我加入两个 DataFrame。

我有两个 DataFrame。

df1:

index   val1    val2
--------------------
1       str1    abc1
2       str2    abc2
3       str3    abc3
4       str4    abc9
5       str5    abc4

df2:

index   val2
------------
1       abc1
2       abc2
4       abc3 
5       abc4
9       abc5

我需要基于前两个创建一个 DataFrame,并通过两列左连接。列 index 和 val2 在两个 DataFrame 中具有相同的名称。 df3 的结果应该是这样的:

index   val1    val2    val3
----------------------------
1       str1    abc1    1
2       str2    abc2    1
3       str3    abc3    NaN
4       str4    abc9    NaN
5       str5    abc4    1

应删除 df1 中不存在的 df2 索引,如果 df1 中的索引具有与 df2 中相同的 val2,则应将 1 添加到新列 val3,否则:NaN。

提前非常感谢!

【问题讨论】:

index一个名为索引的列还是DataFrame的实际索引? 【参考方案1】:

您可以尝试将join默认为左)与rsuffix 一起使用,以便使用后缀重命名 df2 的列名。然后,使用np.where 检查列值是否匹配并为val3 列赋值。

import numpy as np

df = df1.join(df2, rsuffix='_df2')
df['val3'] = np.where(df.val2 == df.val2_df2, 1, np.NaN)
del df['val2_df2']
print(df)

结果:

       val1  val2  val3
index                  
1      str1  abc1   1.0
2      str2  abc2   1.0
3      str3  abc3   NaN
4      str4  abc9   NaN
5      str5  abc4   1.0

【讨论】:

【参考方案2】:

由于您想要合并索引和列的组合,您可以将它们全部添加到索引中,或者在合并之前添加reset_index。我们还将val3 列分配给 df2 以便它被合并。

(df1.reset_index().merge(
     df2.reset_index().assign(val3 = 1), on=['index', 'val2'], how='left')
    .set_index('index'))

输出:

       val1  val2  val3
index                  
1      str1  abc1   1.0
2      str2  abc2   1.0
3      str3  abc3   NaN
4      str4  abc9   NaN
5      str5  abc4   1.0

如果'index' 只是一个列而不是索引,那么它就像指定两个要合并的键一样简单。

df1.merge(df2.assign(val3 = 1), on=['index', 'val2'], how='left')

输出:

   index  val1  val2  val3
0      1  str1  abc1   1.0
1      2  str2  abc2   1.0
2      3  str3  abc3   NaN
3      4  str4  abc9   NaN
4      5  str5  abc4   1.0

【讨论】:

【参考方案3】:

这是一种方式。如下所示,我建议您使用布尔值而不是 float 来表示 val3,因为这就是系列所代表的。

# merge and set index
res = df1.merge(df2, how='left').set_index('index')

# map val2 from df2
res['val3'] = df2.set_index('index')['val2']

# check for equality of val3 and val2
res['val3'] = res['val3'] == res['val2']

print(res)

       val1  val2   val3
index                   
1      str1  abc1   True
2      str2  abc2   True
3      str3  abc3  False
4      str4  abc9  False
5      str5  abc4   True

【讨论】:

以上是关于Pandas 通过两列左连接 DataFrames的主要内容,如果未能解决你的问题,请参考以下文章

python 连接Pandas DataFrames(来自http://pandas.pydata.org/pandas-docs/stable/merging.html)

pandas 有效地将 DataFrames 与不匹配的分类列和 MultiIndex 级别连接起来

用循环生成的连接pandas DataFrames

Pandas:在具有不同名称的字段上加入 DataFrames?

pandas,读取或存储DataFrames的数据到mysql中

如何通过选择特定时间间隔内的时间来索引 pandas DataFrames?