Bagaimana cara mendapatkan daftar semua item duplikat menggunakan panda dengan python?

129

Saya memiliki daftar item yang kemungkinan memiliki beberapa masalah ekspor. Saya ingin mendapatkan daftar item duplikat sehingga saya dapat membandingkannya secara manual. Ketika saya mencoba menggunakan metode duplikat panda , itu hanya mengembalikan duplikat pertama. Apakah ada cara untuk mendapatkan semua duplikat dan bukan hanya yang pertama?

Subbagian kecil dari kumpulan data saya terlihat seperti ini:

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

Kode saya terlihat seperti ini saat ini:

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

Ada beberapa item duplikat. Tapi, ketika saya menggunakan kode di atas, saya hanya mendapatkan item pertama. Dalam referensi API, saya melihat bagaimana saya bisa mendapatkan item terakhir, tetapi saya ingin memiliki semuanya sehingga saya dapat memeriksanya secara visual untuk melihat mengapa saya mendapatkan perbedaan tersebut. Jadi, dalam contoh ini saya ingin mendapatkan ketiga entri A036 dan 11795 entri dan entri duplikat lainnya, bukan yang pertama saja. Apapun bantuannya sangat dihargai.

Besar
sumber
1
"Duplikat" dapat berarti berbagai hal "Dalam kasus Anda, Anda hanya ingin mempertimbangkan duplikat dalam satu kolomID , bukan" baris identik dalam beberapa atau semua kolom ".
smci

Jawaban:

170

Metode # 1: Cetak semua baris di mana ID adalah salah satu ID yang digandakan:

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

tapi saya tidak bisa memikirkan cara yang bagus untuk mencegah pengulangan berulang idskali. Saya lebih suka metode # 2: groupbypada 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
DSM
sumber
11
Metode # 2 sempurna! Terima kasih banyak.
BigHandsome
4
Metode # 2 gagal ("Tidak ada objek untuk digabungkan") jika tidak ada dups
CPBL
4
apa yang g for _ dilakukan?
pengguna77005
5
@ user77005 Anda mungkin sudah tahu sudah, tapi untuk kepentingan semua orang, itu berbunyi seperti ini: g for (placeholder, g) in df.groupby('bla') if 'bla'; garis bawah adalah simbol khas untuk placeholder argumen yang tak terhindarkan di mana kita tidak ingin menggunakannya untuk apa pun dalam ekspresi seperti lambda.
stucash
7
Metode # 1 perlu diperbarui: sorttidak digunakan lagi untuk DataFrames yang mendukung salah satu sort_valuesatau sort_index T&J Terkait SO
tatlar
138

Dengan Pandas versi 0.17, Anda dapat menyetel 'keep = False' di fungsi duplikat untuk mendapatkan semua item duplikat.

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
pengguna666
sumber
3
Bingo, itulah jawabannya. Jadi: str atau str atau boolean ... pilihan API aneh. 'all'akan menjadi IMO yang lebih logis dan intuitif.
Jarad
93
df[df.duplicated(['ID'], keep=False)]

itu akan mengembalikan semua baris duplikat kembali kepada Anda.

Menurut dokumentasi :

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

  • first: Tandai duplikat sebagai True kecuali untuk kemunculan pertama.
  • terakhir: Tandai duplikat sebagai True kecuali untuk kemunculan terakhir.
  • Salah: Tandai semua duplikat sebagai Benar.
Kelly ChowChow
sumber
@dreme ini tidak benar secara sintatis, juga tidak berhasil. ']' Tidak cocok dan juga tidak mengembalikan apa yang mereka butuhkan. Ini lebih pendek, tapi salah.
FinancialRadDeveloper
Ups, Anda benar @FinancialRadDeveloper, dalam kedua hal tersebut. Saya akan menghapus komentar saya. Terima kasih telah menerima kesalahannya.
dreme
4
df [df ['ID']. duplikasi () == True] Ini akan mengembalikan semua duplikat
Hariprasad
12

Karena saya tidak dapat berkomentar, maka posting sebagai jawaban terpisah

Untuk menemukan duplikat berdasarkan lebih dari satu kolom, sebutkan setiap nama kolom seperti di bawah ini, dan itu akan mengembalikan Anda semua kumpulan baris duplikat:

df[df[['product_uid', 'product_title', 'user']].duplicated() == True]
Deepak
sumber
10
df[df['ID'].duplicated() == True]

Ini berhasil untuk saya

Hariprasad
sumber
2
Anda sebenarnya tidak perlu menambahkan == True, .duplicated()sudah mengembalikan array bool.
Jakub Wagner
3

Menggunakan logika bijak-elemen atau dan menyetel argumen take_last dari metode duplikat panda ke True dan False, Anda dapat memperoleh satu set dari kerangka data Anda yang menyertakan semua duplikat.

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

Ini mungkin bukan solusi untuk pertanyaan, tetapi untuk mengilustrasikan contoh:

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)

Keluarannya:

   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
yoonghm
sumber
2

sort("ID")tampaknya tidak berfungsi sekarang, sepertinya tidak digunakan lagi sesuai dokumen pengurutan , jadi gunakan sort_values("ID")sebagai gantinya untuk mengurutkan setelah filter duplikat, seperti berikut:

df[df.ID.duplicated(keep=False)].sort_values("ID")
Nafeez Quraishi
sumber
2

Untuk database saya yang digandakan (keep = False) tidak berfungsi sampai kolom diurutkan.

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

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

PREM JILLA
sumber
4
Tolong, bisakah Anda memperpanjang jawaban Anda dengan penjelasan yang lebih rinci? Ini akan sangat berguna untuk pemahaman. Terima kasih!
vezunchik
Selamat datang di Stack Overflow dan terima kasih atas kontribusi Anda! Alangkah baiknya jika Anda bisa memperpanjang jawaban Anda dengan penjelasan. Di sini Anda menemukan panduan Bagaimana memberikan jawaban yang baik . Terima kasih!
David