【问题标题】:Pandas left join DataFrames by two columnsPandas 通过两列左连接 DataFrames
【发布时间】: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的实际索引?

标签: python pandas dataframe merge


【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 2023-02-24
        • 2023-01-25
        • 1970-01-01
        • 2020-03-31
        • 1970-01-01
        • 2019-05-14
        • 2021-06-20
        • 2019-07-03
        相关资源
        最近更新 更多