【问题标题】:How can I join 2 pandas dataframe using left join?如何使用左连接加入 2 个熊猫数据框?
【发布时间】:2021-10-16 22:53:12
【问题描述】:

我有 2 个数据框需要使用左连接来连接。在 sql 中,我的查询为

SELECT A.* INTO NewTable FROM A LEFT JOIN B ON A.id=B.id WHERE B.id IS NULL;

我有 2 个数据框: df1:

id name
1 one
2 two
3 three
4 four

df2:

id
2
3

我期待的是:

id name
1 one
4 four

我尝试了什么?

common = df1.merge(df2, on=['id', 'id'])
result = df1[~df1.id.isin(common.id)]

我得到的结果比查询返回的结果更多。任何帮助表示赞赏。

【问题讨论】:

    标签: python pandas dataframe data-analysis


    【解决方案1】:

    您可以在.merge() 开启indicator= 参数的情况下使用左连接。然后,用.query()过滤等于"left_only"的指标值,如下:

    df1.merge(df2, on='id', how='left', indicator='ind').query('ind == "left_only"')
    

    结果:

       id  name        ind
    0   1   one  left_only
    3   4  four  left_only
    

    您可以选择删除指示符列,如下所示:

    df1.merge(df2, on='id', how='left', indicator='ind').query('ind == "left_only"').drop('ind', axis=1)
    

    结果:

       id  name
    0   1   one
    3   4  four
    

    【讨论】:

    • 让我失望的是,当我运行查询时,我得到的记录数量更少,而使用 pandas 方法我得到的记录更多。
    • @ChinwalPrasad 您是指 SQL 查询还是我的代码中的 .query()?我的代码给你正确的结果吗?
    • 所以我的意思是当我运行 sql 查询时,我得到了大约 2200 条记录。但是当我使用你的方法时,我的数据框有大约 6600 条记录。
    • @ChinwalPrasad 只是想与您再次确认您的预期结果。您希望从df1 中获取过滤后的行,同时从df1 中删除这些行,如果这些行具有id 也出现在df2 中。它是否正确 ?如果是,您是否从 6600 条记录中看到来自 df2 的任何应该被删除但未能删除的行?
    • @ChinwalPrasad 您的 df2 是否有其他列与 df1 具有相同的列标签?如果是,请使用我上面编辑的代码。修改为在合并期间添加 on='id',以便仅显式匹配 id 列。旧代码基于您的示例数据,在df2 中没有其他列。请重试。
    【解决方案2】:

    你有正确的解决方案,只有你错误地解释了结果。

    这将为您提供没有索引的结果

    import pandas as pd
    d = {'id': [1, 2,3,4], 'col2': ['one','two','three','four']}
    d1 = {'id': [2,3]}
    
    df1 = pd.DataFrame(data=d)
    
    df2 =  pd.DataFrame(data=d1)
    
    
    result = df1[~df1.id.isin(df2.id)]
    print(result.to_string(index=False))
    

    【讨论】:

      【解决方案3】:
      import pandas as pd
      import numpy as np
      
      df1 = pd.DataFrame(np.array([[1, "one"], [2, "two"], [3, "three"], [4, "four"]]),
                         columns=['id', 'name '])
      
      df2 = pd.DataFrame(np.array([[1], [2]]),
                         columns=['id'])
      

      df1.drop(df2['id'], axis=0,inplace=True)
      df1
      

      【讨论】:

        【解决方案4】:

        试试:

        print(df1[~df1["id"].isin(df2["id"])])
        

        打印:

           id  name
        0   1   one
        3   4  four
        

        【讨论】:

        • 不幸的是,这种方法的结果相同。
        猜你喜欢
        • 2013-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-14
        • 1970-01-01
        • 2015-12-23
        • 1970-01-01
        相关资源
        最近更新 更多