如何使用python中的pandas获取所有重复项的列表?


124

我列出了可能存在一些出口问题的物品清单。我想获得重复项的列表,以便可以手动比较它们。当我尝试使用pandas 重复方法时,它仅返回第一个重复。有没有办法获取所有重复项,而不仅仅是第一个?

我的数据集的一个小部分看起来像这样:

ID,ENROLLMENT_DATE,TRAINER_MANAGING,TRAINER_OPERATOR,FIRST_VISIT_DATE
1536D,12-Feb-12,"06DA1B3-Lebanon NH",,15-Feb-12
F15D,18-May-12,"06405B2-Lebanon NH",,25-Jul-12
8096,8-Aug-12,"0643D38-Hanover NH","0643D38-Hanover NH",25-Jun-12
A036,1-Apr-12,"06CB8CF-Hanover NH","06CB8CF-Hanover NH",9-Aug-12
8944,19-Feb-12,"06D26AD-Hanover NH",,4-Feb-12
1004E,8-Jun-12,"06388B2-Lebanon NH",,24-Dec-11
11795,3-Jul-12,"0649597-White River VT","0649597-White River VT",30-Mar-12
30D7,11-Nov-12,"06D95A3-Hanover NH","06D95A3-Hanover NH",30-Nov-11
3AE2,21-Feb-12,"06405B2-Lebanon NH",,26-Oct-12
B0FE,17-Feb-12,"06D1B9D-Hartland VT",,16-Feb-12
127A1,11-Dec-11,"064456E-Hanover NH","064456E-Hanover NH",11-Nov-12
161FF,20-Feb-12,"0643D38-Hanover NH","0643D38-Hanover NH",3-Jul-12
A036,30-Nov-11,"063B208-Randolph VT","063B208-Randolph VT",
475B,25-Sep-12,"06D26AD-Hanover NH",,5-Nov-12
151A3,7-Mar-12,"06388B2-Lebanon NH",,16-Nov-12
CA62,3-Jan-12,,,
D31B,18-Dec-11,"06405B2-Lebanon NH",,9-Jan-12
20F5,8-Jul-12,"0669C50-Randolph VT",,3-Feb-12
8096,19-Dec-11,"0649597-White River VT","0649597-White River VT",9-Apr-12
14E48,1-Aug-12,"06D3206-Hanover NH",,
177F8,20-Aug-12,"063B208-Randolph VT","063B208-Randolph VT",5-May-12
553E,11-Oct-12,"06D95A3-Hanover NH","06D95A3-Hanover NH",8-Mar-12
12D5F,18-Jul-12,"0649597-White River VT","0649597-White River VT",2-Nov-12
C6DC,13-Apr-12,"06388B2-Lebanon NH",,
11795,27-Feb-12,"0643D38-Hanover NH","0643D38-Hanover NH",19-Jun-12
17B43,11-Aug-12,,,22-Oct-12
A036,11-Aug-12,"06D3206-Hanover NH",,19-Jun-12

我的代码当前如下所示:

df_bigdata_duplicates = df_bigdata[df_bigdata.duplicated(cols='ID')]

那里有几个重复的物品。但是,当我使用上面的代码时,我只会得到第一项。在API参考中,我看到了如何获得最后一个项目,但是我希望拥有所有这些项目,因此我可以目视检查它们,以查看为什么我得到了差异。因此,在此示例中,我想获得所有三个A036条目以及11795条目和任何其他重复的条目,而不是仅第一个。任何帮助深表感谢。


“重复”可以指各种事物”在你的情况,你只需要考虑在单个列的重复ID,而不是‘多行相同或所有列。’
SMCI

Answers:


167

方法1:打印所有ID为重复ID之一的行:

>>> import pandas as pd
>>> df = pd.read_csv("dup.csv")
>>> ids = df["ID"]
>>> df[ids.isin(ids[ids.duplicated()])].sort("ID")
       ID ENROLLMENT_DATE        TRAINER_MANAGING        TRAINER_OPERATOR FIRST_VISIT_DATE
24  11795       27-Feb-12      0643D38-Hanover NH      0643D38-Hanover NH        19-Jun-12
6   11795        3-Jul-12  0649597-White River VT  0649597-White River VT        30-Mar-12
18   8096       19-Dec-11  0649597-White River VT  0649597-White River VT         9-Apr-12
2    8096        8-Aug-12      0643D38-Hanover NH      0643D38-Hanover NH        25-Jun-12
12   A036       30-Nov-11     063B208-Randolph VT     063B208-Randolph VT              NaN
3    A036        1-Apr-12      06CB8CF-Hanover NH      06CB8CF-Hanover NH         9-Aug-12
26   A036       11-Aug-12      06D3206-Hanover NH                     NaN        19-Jun-12

但是我想不出一种防止重复ids很多次的好方法。我更喜欢groupbyID上的方法2 :。

>>> pd.concat(g for _, g in df.groupby("ID") if len(g) > 1)
       ID ENROLLMENT_DATE        TRAINER_MANAGING        TRAINER_OPERATOR FIRST_VISIT_DATE
6   11795        3-Jul-12  0649597-White River VT  0649597-White River VT        30-Mar-12
24  11795       27-Feb-12      0643D38-Hanover NH      0643D38-Hanover NH        19-Jun-12
2    8096        8-Aug-12      0643D38-Hanover NH      0643D38-Hanover NH        25-Jun-12
18   8096       19-Dec-11  0649597-White River VT  0649597-White River VT         9-Apr-12
3    A036        1-Apr-12      06CB8CF-Hanover NH      06CB8CF-Hanover NH         9-Aug-12
12   A036       30-Nov-11     063B208-Randolph VT     063B208-Randolph VT              NaN
26   A036       11-Aug-12      06D3206-Hanover NH                     NaN        19-Jun-12

11
方法2就是完美的!非常感谢。
BigHandsome

4
如果没有复制,则方法2失败(“没有要连接的对象”)
CPBL

4
怎么g for _ 办?
user77005

5
@ user77005你可能已经想通了,但每个人的利益,其内容是这样的:g for (placeholder, g) in df.groupby('bla') if 'bla'; 下划线是不可避免的参数占位符的典型符号,此处我们不希望将其用于类似lambda的表达式中的任何内容。
stucash

7
方法#1需要更新:sort不推荐使用DataFrame,而推荐使用sort_valuessort_index 相关SO Q&A
tatlar

137

在Pandas版本0.17中,您可以在重复函数中设置“ keep = False”,以获取所有重复项。

In [1]: import pandas as pd

In [2]: df = pd.DataFrame(['a','b','c','d','a','b'])

In [3]: df
Out[3]: 
       0
    0  a
    1  b
    2  c
    3  d
    4  a
    5  b

In [4]: df[df.duplicated(keep=False)]
Out[4]: 
       0
    0  a
    1  b
    4  a
    5  b

3
宾果游戏,有答案。所以:str或str或boolean ...奇怪的API选择。'all'会更符合逻辑和直观的IMO。
Jarad '18

91
df[df.duplicated(['ID'], keep=False)]

它将所有重复的行返回给您。

根据文件

keep:{'first','last',False},默认为'first'

  • first:将第一次出现的重复项标记为True。
  • last:将最后一次出现的重复项标记为True。
  • False:将所有重复项标记为True。

@dreme这在语法上不正确,也不起作用。如果不匹配']',也不会返回所需的内容。它较短,但错误。
FinancialRadDeveloper

糟糕,在这两个方面,您都正确@FinancialRadDeveloper。我将删除我的评论。感谢您发现错误。
dreme

3
df [df ['ID']。duplicated()== True]这将返回所有重复项
Hariprasad

12

由于我无法发表评论,因此将其发布为单独的答案

要在多个列的基础上查找重复项,请提及以下每个列名,它将返回所有已设置的重复行:

df[df[['product_uid', 'product_title', 'user']].duplicated() == True]


3

使用按元素进行逻辑运算或将pandas复制方法的take_last参数设置为True和False,您可以从数据框中获取一个包含所有重复项的集合。

df_bigdata_duplicates = 
    df_bigdata[df_bigdata.duplicated(cols='ID', take_last=False) |
               df_bigdata.duplicated(cols='ID', take_last=True)
              ]

2

这可能不是解决问题的方法,而是举例说明:

import pandas as pd

df = pd.DataFrame({
    'A': [1,1,3,4],
    'B': [2,2,5,6],
    'C': [3,4,7,6],
})

print(df)
df.duplicated(keep=False)
df.duplicated(['A','B'], keep=False)

输出:

   A  B  C
0  1  2  3
1  1  2  4
2  3  5  7
3  4  6  6

0    False
1    False
2    False
3    False
dtype: bool

0     True
1     True
2    False
3    False
dtype: bool


2

对于我的数据库,在对列进行排序之前,重复的(keep = False)不起作用。

data.sort_values(by=['Order ID'], inplace=True)
df = data[data['Order ID'].duplicated(keep=False)]

1

df[df.duplicated(['ID'])==True].sort_values('ID')


4
请,您可以用更详细的解释来扩展您的答案吗?这对于理解非常有用。谢谢!
vezunchik

欢迎使用Stack Overflow,感谢您的贡献!如果您可以通过解释来扩展答案,那将是一种好感。在这里,您可以找到有关如何给出良好答案的指南。谢谢!
大卫,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.