Як я можу отримати список всіх повторюваних елементів, використовуючи панди в python?


127

У мене є список товарів, які, ймовірно, мають деякі проблеми з експортом. Я хотів би отримати список повторюваних елементів, щоб я міг їх порівнювати вручну. Коли я намагаюся використовувати дублюваний метод панд , він повертає лише перший дублікат. Чи є спосіб отримати всі дублікати, а не лише перший?

Невеликий підрозділ мого набору даних виглядає приблизно так:

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 записів та будь-які інші дублювані записи, а не першу. Будь-яка допомога найбільше цінується.


1
"Дублікати" можуть означати різні речі "У вашому випадку ви хочете розглянути дублікати лише в одному стовпчикуID , а не" рядки однакові у кількох чи всіх стовпцях ".
smci

Відповіді:


170

Спосіб №1: надрукуйте всі рядки, де ідентифікатор є одним із ідентифікаторів, що дублюються:

>>> 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стільки разів. Я віддаю перевагу метод №2: groupbyна ідентифікатор.

>>> 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'; підкреслення є типовим символом для заповнювача неминучого аргументу, коли ми не хочемо використовувати його ні для чого в виразі, подібному до лямбда.
ліпнина

7
Спосіб № 1 потребує оновлення: sortбув знятий для DataFrames на користь будь-якого sort_valuesабо sort_index пов'язаного SO Q&A
tatlar

138

З версією 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'було б більш логічним та інтуїтивним ІМО.
Ярад

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

він поверне вам всі повторювані рядки.

Відповідно до документації :

утримуйте: {'first', 'last', False}, за замовчуванням 'first'

  • по-перше: позначте дублікати як істинне, за винятком першого виникнення.
  • останнє: позначте дублікати як істинне, за винятком останнього явища.
  • Неправильно: позначте всі дублікати як істинні.

@dreme це не синтаксично правильно, і це не працює. Невідповідність ']', а також не повертає те, що їм потрібно. Його коротше, але неправильно.
FinancialRadDeveloper

На жаль, ви маєте рацію @FinancialRadDeveloper в обох випадках. Я видалю свій коментар. Дякуємо за виявлення помилки.
dreme

3
df [df ['ID']. duplicate () == True] Це поверне всі дублікати
Hariprasad

12

Як я не можу коментувати, отже, повідомлення як окрему відповідь

Щоб знайти дублікати на основі більш ніж одного стовпця, згадайте кожну назву стовпця, як показано нижче, і вона поверне вам усі набір дублікатів рядків:

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


3

Використовуючи логічну функцію або встановивши аргумент 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

sort("ID")Здається, це не працює зараз, здається застарілим відповідно до сортування doc , тому використовуйте sort_values("ID")натомість для сортування за дублікатами фільтр наступним чином:

df[df.ID.duplicated(keep=False)].sort_values("ID")

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 та дякуємо за ваш внесок! Було б добро, якби ви могли поширити відповідь поясненням. Тут ви знайдете посібник Як дати гарну відповідь . Дякую!
Девід
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.