【问题标题】:Merge "one-to-one" dataframe in pandas在熊猫中合并“一对一”数据框
【发布时间】:2018-04-16 02:43:38
【问题描述】:

我有两个数据框:

df1 = pd.DataFrame(data = 
{'Invoice' : [1, 2, 3, 4, 5], 'Value' : [10, 25, 40, 10, 15]}) 
df2 = pd.DataFrame(data =
{'Invoice' : [2, 3, 5, 2], 'Value' : [25, 11, 15,25], 'TestData':["A",'B','C','D']})  

我已经合并它们并得到 df3:

df3=pd.merge(df1,df2, left_on=["Invoice","Value"], right_on=["Invoice","Value"])

Df3 输出:

   Invoice    Value   TestData
0      2    25        A
1      2    25        D
2      5    15        C

我的问题是如何使用“一对一”获得合并的数据框(我的意思是 - 当发票编号 2 在两个数据框中的一个中仅出现一次(或通常更少)时,请不要使用发票创建另一行合并数据框中的第 2 号)。我想得到这样的东西:

   Invoice    Value   TestData
0      2    25        A
1      5    15        C

或者这个:

   Invoice    Value   TestData
0      2    25        D
1      5    15        C

我只尝试了左右合并,但这不起作用 - 发票编号为 2 的行总是有两行。

谢谢你,
贾雷克

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    使用drop_duplicates 指定列名,参数keep='last' 用于最后一个重复行:

    df2 = df2.drop_duplicates(["Invoice","Value"])
    #same as
    #df2 = df2.drop_duplicates(["Invoice","Value"], keep='first')
    df3=pd.merge(df1,df2, on=["Invoice","Value"])
    print (df3)
       Invoice  Value TestData
    0        2     25        A
    1        5     15        C
    

    df2 = df2.drop_duplicates(["Invoice","Value"], keep='last')
    df3=pd.merge(df1,df2, on=["Invoice","Value"])
    print (df3)
       Invoice  Value TestData
    0        2     25        D
    1        5     15        C
    

    编辑:

    如果需要按所有行分组,则需要添加新列以保持唯一性:

    df1['g'] = df1.groupby(['Invoice','Value']).cumcount()
    df2['g'] = df2.groupby(['Invoice','Value']).cumcount()
    
    print (df1)
       Invoice  Value  g
    0        1     10  0
    1        2     25  0
    2        3     40  0
    3        4     10  0
    4        5     15  0
    
    print (df2)
       Invoice TestData  Value  g
    0        2        A     25  0
    1        3        B     11  0
    2        5        C     15  0
    3        2        D     25  1
    
    df3=pd.merge(df1,df2, on=["Invoice","Value", "g"]).drop('g', axis=1)
    print (df3)
       Invoice  Value TestData
    0        2     25        A
    1        5     15        C
    

    【讨论】:

    • 感谢您的回复,但我无法从 df2 中删除这些行,因为我需要它们 - 在这种情况下,双倍值不是错误。假设 df1 包含按一个类别子集的发票,而 df2 由另一个类别子集。目前可能是df1中缺少发票的问题,所以我不能删除重复项。我不能放弃它们的另一个原因是(我认为)我将无法使用用于合并的那些值过滤源 df1 和 df2:df1[(~df1.Invoice.isin(df3.Invoice))&(~df1.Value.isin(df3.Value))] 因为那不是源 df但下降了。 @Zulfiqaar
    • 等一下,我有个主意。
    • 非常感谢!多么聪明的解决方案!我从中学到了很多。我点击了“这个答案很有用”,但我没有声誉,所以我能做的就是:/
    • 如果我的回答对您有帮助,请不要忘记 accept 它 - 单击答案旁边的复选标记 () 将其从灰色切换为已填充。谢谢。跨度>
    • 谢谢 - 我没注意到:/
    【解决方案2】:

    您可以尝试按特定列的去重方法:

    df3.drop_duplicates(subset="Invoice")
    
       Invoice  Value TestData
    0        2     25        A
    2        5     15        C
    

    更多信息:

    https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.drop_duplicates.html

    【讨论】:

      猜你喜欢
      • 2018-07-22
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      相关资源
      最近更新 更多