找出具有重复记录的两个数据框之间的差异

时间:2019-06-06 20:48:23

标签: python pandas dataframe

我有两个产品列表数据框(产品,价格和供应商)

抓取1:

    Product Price   Vendor
0   ABC123  121.50  VendorB
1   GHIJK   76.45   VendorA
2   KLMNOP  55.05   VendorB
3   XYZABC  67.01   VendorC
4   JKJKABC 9.15    VendorX
5   XYZXYZ  78.05   VendorJ
6   XYZ1234 90.90   VendorI

和抓取2:

   Product  Price   Vendor
0   ABC123  121.50  VendorB
1   GHIJK   76.45   VendorA
2   XYZABC  67.01   VendorC
3   JKJKABC 9.15    VendorX
4   XYZ1234 90.90   VendorI
5   HIJKLM  89.75   VendorC
6   LOLOLOL 23.55   VendorI
7   WENDY   89.02   VendorG
8   ROAD123 90.99   Vendor4U
9   FORGE12 67.59   VendorX

我想从中找出列表的区别(即Scrape 2中的新列表和Scrape 1中的已售列表。

我通过对两个数据帧进行合并来做到这一点-

# SOLD LISTINGS - LISTINGS ONLY IN FIRST DATAFRAME
df_sold = df_scrape_1.merge(df_scrape_2,indicator = True, how='left').loc[lambda x : x['_merge']!='both']

# NEW LISTINGS - LISTINGS ONLY IN SECOND DATAFRAME
df_new = df_scrape_1.merge(df_scrape_2,indicator = True, how='right').loc[lambda x : x['_merge']!='both'] 

这给了我正确的结果:2 Sold个列表和5 New个列表。但是当我在其中两个刮擦中都有一些重复的行时,我遇到了问题。

例如,如果Scrape 1有3个重复的ABC123清单,而Scrape 2中只有1个清单,则应显示为2 Sold清单。或者,如果Scrape 1具有1个XYZXYZ列表,而Scrape 2具有3个列表,则应显示为2 New列表。我该如何实现?

编辑:

如果我有Scrape 1:

    Product Price   Vendor
0   ABC123  121.50  VendorB
1   GHIJK   76.45   VendorA
2   KLMNOP  55.05   VendorB
3   XYZABC  67.01   VendorC
4   ABC123  121.50  VendorB
5   JKJKABC 9.15    VendorX
6   XYZXYZ  78.05   VendorJ
7   XYZ1234 90.90   VendorI

,将“抓取2”作为:

   Product  Price   Vendor
0   ABC123  121.50  VendorB
1   GHIJK   76.45   VendorA
2   XYZABC  67.01   VendorC
3   JKJKABC 9.15    VendorX
4   XYZ1234 90.90   VendorI
5   HIJKLM  89.75   VendorC
6   LOLOLOL 23.55   VendorI
7   WENDY   89.02   VendorG
8   ROAD123 90.99   Vendor4U
9   FORGE12 67.59   VendorX
10  XYZABC  67.01   VendorC
11  XYZABC  67.01   VendorC

它应该给我两个分别具有3 Sold清单和7 New清单的数据框。

2 个答案:

答案 0 :(得分:1)

一种简单的方法是为每组重复值添加一个添加整数 index (滚动计数)的列。

例如,让我们将df_scrape_1更改为:

   Product   Price   Vendor
0   ABC123  121.50  VendorB
1    GHIJK   76.45  VendorA
2   KLMNOP   55.05  VendorB
3   XYZABC   67.01  VendorC
4  JKJKABC    9.15  VendorX
5   XYZXYZ   78.05  VendorJ
6  XYZ1234   90.90  VendorI
7   ABC123  121.50  VendorB

其中最后一行与第一行重复。

让我们为两个数据框中的重复行添加滚动计数:

df_scrape_1['num'] = df_scrape_1.groupby(df_scrape_1.columns.tolist()).cumcount()
df_scrape_2['num'] = df_scrape_2.groupby(df_scrape_2.columns.tolist()).cumcount()

df_scrape_1已成为:

   Product   Price   Vendor  num
0   ABC123  121.50  VendorB    0
1    GHIJK   76.45  VendorA    0
2   KLMNOP   55.05  VendorB    0
3   XYZABC   67.01  VendorC    0
4  JKJKABC    9.15  VendorX    0
5   XYZXYZ   78.05  VendorJ    0
6  XYZ1234   90.90  VendorI    0
7   ABC123  121.50  VendorB    1

现在df_sold正在使用您的表达式:

df_sold = df_scrape_1.merge(df_scrape_2,indicator = True,
                            how='left').loc[lambda x : x['_merge']!='both']

给予:

  Product   Price   Vendor  num     _merge
2  KLMNOP   55.05  VendorB    0  left_only
5  XYZXYZ   78.05  VendorJ    0  left_only
7  ABC123  121.50  VendorB    1  left_only

答案 1 :(得分:0)

您发现的一种方法是使用isin,该方法会产生NaN行,您可以将其删除:

differences = df2[~df2.isin(df1)].dropna()