Wie erhalte ich eine Liste aller doppelten Elemente mit Pandas in Python?


124

Ich habe eine Liste von Artikeln, bei denen wahrscheinlich Exportprobleme auftreten. Ich möchte eine Liste der doppelten Elemente erhalten, damit ich sie manuell vergleichen kann. Wenn ich versuche, die duplizierte Methode von pandas zu verwenden , wird nur das erste Duplikat zurückgegeben. Gibt es eine Möglichkeit, alle Duplikate zu erhalten und nicht nur das erste?

Ein kleiner Unterabschnitt meines Datensatzes sieht folgendermaßen aus:

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

Mein Code sieht derzeit so aus:

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

Es gibt ein paar doppelte Gegenstände. Wenn ich jedoch den obigen Code verwende, erhalte ich nur den ersten Artikel. In der API-Referenz sehe ich, wie ich das letzte Element erhalten kann, aber ich möchte alle haben, damit ich sie visuell überprüfen kann, um festzustellen, warum ich die Diskrepanz erhalte. In diesem Beispiel möchte ich also alle drei A036-Einträge und sowohl 11795-Einträge als auch alle anderen duplizierten Einträge anstelle des nur ersten erhalten. Jede Hilfe wird am meisten geschätzt.


"Duplikate" können verschiedene Bedeutungen haben "In Ihrem Fall möchten Sie nur Duplikate in einer einzelnen SpalteID berücksichtigen , nicht" Zeilen, die in mehreren oder allen Spalten identisch sind ".
smci

Antworten:


166

Methode 1: Drucken Sie alle Zeilen, in denen die ID eine der doppelt duplizierten IDs ist:

>>> 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

aber ich konnte mir keinen guten Weg vorstellen, um zu verhindern, dass es idsso oft wiederholt wird. Ich bevorzuge Methode 2: groupbyauf der ID.

>>> 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
Methode 2 ist einfach perfekt! Ich danke dir sehr.
BigHandsome

4
Methode 2 schlägt fehl ("Keine zu verkettenden Objekte"), wenn keine Dups vorhanden sind
CPBL

4
was macht g for _ das
user77005

5
@ user77005 Sie haben es vielleicht schon herausgefunden, aber zum Wohle aller lautet es wie folgt : g for (placeholder, g) in df.groupby('bla') if 'bla'; Der Unterstrich ist ein typisches Symbol für den Platzhalter eines unvermeidlichen Arguments, bei dem wir ihn für nichts in einem Lambda-ähnlichen Ausdruck verwenden möchten.
stucash

7
Methode Nr. 1 muss aktualisiert werden: sortwurde für DataFrames zugunsten von sort_valuesoder sort_index verwandten SO Q & A
tatlar

136

Mit Pandas Version 0.17 können Sie in der duplizierten Funktion 'keep = False' setzen , um alle doppelten Elemente abzurufen.

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
Bingo, da ist die Antwort. Also: str oder str oder boolean ... ungerade API-Auswahl. 'all'wäre logischer und intuitiver IMO.
Jarad

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

Alle duplizierten Zeilen werden an Sie zurückgegeben.

Laut Dokumentation :

behalte: {'first', 'last', False}, default 'first'

  • first: Markiere Duplikate bis auf das erste Vorkommen als True.
  • last: Markiert Duplikate bis auf das letzte Vorkommen als True.
  • False: Markieren Sie alle Duplikate als True.

@dreme das ist syntaktisch nicht korrekt und funktioniert auch nicht. Nicht übereinstimmend ']' und es gibt auch nicht zurück, was sie brauchen. Es ist kürzer, aber falsch.
FinancialRadDeveloper

Hoppla, Sie haben in beiden Punkten Recht @FinancialRadDeveloper. Ich werde meinen Kommentar löschen. Vielen Dank, dass Sie den Fehler behoben haben.
Dreme

3
df [df ['ID']. duplicated () == True] Dies gibt alle Duplikate zurück
Hariprasad

12

Da ich keinen Kommentar abgeben kann, wird dies als separate Antwort veröffentlicht

Um Duplikate auf der Grundlage von mehr als einer Spalte zu finden, geben Sie jeden Spaltennamen wie folgt an. Daraufhin werden alle festgelegten doppelten Zeilen zurückgegeben:

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

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

Das hat bei mir funktioniert


2
Sie müssen eigentlich nicht hinzufügen == True, gibt .duplicated()bereits bool Array zurück.
Jakub Wagner

3

Wenn Sie ein elementweises logisches oder verwenden und das Argument take_last der duplizierten Pandas-Methode auf True und False setzen, können Sie aus Ihrem Datenrahmen einen Satz abrufen, der alle Duplikate enthält.

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

2

Dies ist möglicherweise keine Lösung für die Frage, sondern dient zur Veranschaulichung von Beispielen:

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)

Die Ausgänge:

   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")scheint jetzt nicht zu funktionieren, scheint gemäß Sortierdokument veraltet zu sein , also verwenden Sie sort_values("ID")stattdessen, um nach doppeltem Filter zu sortieren, wie folgt:

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

2

Für meine Datenbank funktionierte dupliziert (keep = False) nicht, bis die Spalte sortiert wurde.

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
Können Sie bitte Ihre Antwort mit einer detaillierteren Erklärung erweitern? Dies ist sehr nützlich für das Verständnis. Danke dir!
vezunchik

Willkommen bei Stack Overflow und vielen Dank für Ihren Beitrag! Es wäre nett, wenn Sie Ihre Antwort durch eine Erklärung erweitern könnten. Hier finden Sie eine Anleitung, wie Sie eine gute Antwort geben können . Vielen Dank!
David
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.