Usuń wszystkie zduplikowane wiersze w Python Pandas

160

pandas drop_duplicatesFunkcja jest wielki dla „uniquifying” do dataframe. Jednak jednym z argumentów słów kluczowych do przekazania jest take_last=Truelub take_last=False, podczas gdy chciałbym usunąć wszystkie wiersze, które są duplikatami w podzbiorze kolumn. czy to możliwe?

    A   B   C
0   foo 0   A
1   foo 1   A
2   foo 1   B
3   bar 1   A

Jako przykład chciałbym spaść wiersze, które odpowiadają na kolumnach Ai Ctak to powinno spaść wiersze 0 i 1.

Jamie Bull
źródło

Odpowiedzi:

235

Jest to teraz znacznie łatwiejsze w pandach dzięki drop_duplicates i parametrowi keep.

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.drop_duplicates(subset=['A', 'C'], keep=False)
Ben
źródło
2
Co się stanie, jeśli moje kolumny nie są wyraźnie oznaczone? Jak wybrać kolumny tylko na podstawie ich indeksu?
Hamman Samuel
2
Może df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)?
Ben
5
możesz spróbowaćdf.drop_duplicates(subset=[df.columns[0:2]], keep = False)
seeiespi
68

Chcę tylko dodać do odpowiedzi Bena na drop_duplicates :

keep : {'pierwsza', 'ostatnia', False}, domyślna 'pierwsza'

  • pierwszy: Usuń duplikaty z wyjątkiem pierwszego wystąpienia.

  • last: Usuń duplikaty z wyjątkiem ostatniego wystąpienia.

  • Fałsz: usuń wszystkie duplikaty.

Więc ustawienie keepFałsz da ci pożądaną odpowiedź.

DataFrame.drop_duplicates (* args, ** kwargs) Zwróć DataFrame z usuniętymi zduplikowanymi wierszami, opcjonalnie biorąc pod uwagę tylko niektóre kolumny

Parametry: podzbiór: etykieta kolumny lub sekwencja etykiet, opcjonalne Uwzględnij tylko niektóre kolumny do identyfikacji duplikatów, domyślnie użyj wszystkich kolumn zachowaj: {'pierwsza', 'ostatnia', False}, domyślna 'pierwsza' pierwsza: Usuń duplikaty z wyjątkiem za pierwsze wystąpienie. last: Usuń duplikaty z wyjątkiem ostatniego wystąpienia. Fałsz: usuń wszystkie duplikaty. take_last: przestarzałe inplace: boolean, default False Czy usunąć duplikaty w miejsce, czy zwrócić kopię cols: kwargs only argument of subset [deprecated] Returns: deduplicated: DataFrame

Jake
źródło
26

Jeśli chcesz, aby wynik był przechowywany w innym zbiorze danych:

df.drop_duplicates(keep=False)

lub

df.drop_duplicates(keep=False, inplace=False)

Jeśli ten sam zbiór danych wymaga aktualizacji:

df.drop_duplicates(keep=False, inplace=True)

Powyższe przykłady usuwają wszystkie duplikaty i zachowują jeden, podobnie jak DISTINCT *w SQL

Ramanujam Allam
źródło
12

używać groupbyifilter

import pandas as pd
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"], "B":[0,1,1,1], "C":["A","A","B","A"]})
df.groupby(["A", "C"]).filter(lambda df:df.shape[0] == 1)
HYRY
źródło
5

Właściwie upuść tylko wiersze 0 i 1 (zachowywane są wszystkie obserwacje zawierające dopasowane A i C):

In [335]:

df['AC']=df.A+df.C
In [336]:

print df.drop_duplicates('C', take_last=True) #this dataset is a special case, in general, one may need to first drop_duplicates by 'c' and then by 'a'.
     A  B  C    AC
2  foo  1  B  fooB
3  bar  1  A  barA

[2 rows x 4 columns]

Ale podejrzewam, że naprawdę chcesz tego (zachowywana jest jedna obserwacja zawierająca dopasowane A i C):

In [337]:

print df.drop_duplicates('AC')
     A  B  C    AC
0  foo  0  A  fooA
2  foo  1  B  fooB
3  bar  1  A  barA

[3 rows x 4 columns]

Edytować:

Teraz jest znacznie jaśniej, dlatego:

In [352]:
DG=df.groupby(['A', 'C'])   
print pd.concat([DG.get_group(item) for item, value in DG.groups.items() if len(value)==1])
     A  B  C
2  foo  1  B
3  bar  1  A

[2 rows x 3 columns]
CT Zhu
źródło
1
Gdyby tego właśnie chciałem, użyłbym po prostu, df.drop_duplicates(['A','C'])ponieważ domyślnie zachowuje jedną obserwację jako pierwszą lub ostatnią, jak wspomniałem w pytaniu - chociaż właśnie zdałem sobie sprawę, że słowo kluczowe jest błędne, pisząc z pamięci. Chcę usunąć wszystkie wiersze, które są identyczne w interesujących nas kolumnach (A i C w przykładowych danych).
Jamie Bull
0

Wypróbuj te różne rzeczy

df = pd.DataFrame({"A":["foo", "foo", "foo", "bar","foo"], "B":[0,1,1,1,1], "C":["A","A","B","A","A"]})

>>>df.drop_duplicates( "A" , keep='first')

lub

>>>df.drop_duplicates( keep='first')

lub

>>>df.drop_duplicates( keep='last')
Priyansh gupta
źródło