Laat alle dubbele rijen over meerdere kolommen vallen in Python Panda’s

De functie pandasdrop_duplicatesis geweldig voor het “uniquificeren” van een dataframe. Een van de sleutelwoordargumenten om door te geven is echter take_last=Trueof take_last=False, terwijl ik alle rijen die duplicaten zijn over een subset van kolommen zou willen verwijderen. Is dit mogelijk?

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

Als voorbeeld wil ik rijen verwijderen die overeenkomen met de kolommen Aen C, dus dit zou rijen 0 en 1 moeten laten vallen.


Antwoord 1, autoriteit 100%

Dit is nu veel gemakkelijker in panda’s met drop_duplicatesen de keep-parameter.

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)

Antwoord 2, autoriteit 31%

Ik wil alleen iets toevoegen aan het antwoord van Ben op drop_duplicates:

keep: {‘first’, ‘last’, False}, standaard ‘first’

  • first : Duplicaten verwijderen behalve de eerste keer.

  • laatste : Duplicaten verwijderen behalve de laatste keer.

  • Niet waar: verwijder alle duplicaten.

Dus als u keepinstelt op False, krijgt u het gewenste antwoord.

DataFrame.drop_duplicates(*args, **kwargs) Retourneer DataFrame met
dubbele rijen verwijderd, eventueel alleen rekening houdend met bepaalde kolommen

Parameters: subset: kolomlabel of -sequentie van labels, optioneel
Overweeg alleen bepaalde kolommen voor het identificeren van duplicaten, standaard
Gebruik alle kolommen HOUD: {‘First’, ‘Laatste’, FALSE}, standaard
‘Eerste’ eerst: druppel duplicaten behalve het eerste voorval. laatste
: DROP DUPLICATEN behalve voor het laatste voorval. FALSE: laat alles vallen
duplicaten. Take_LAST: Verouderde inplace: Boolean, standaard false
Om duplicaten op zijn plaats te laten vallen of om een ​​Copy Cols te retourneren: Kwargs
Alleen argument van subset [verouderd] retourneert: Dedupliced:
Dataframe


Antwoord 3, Autoriteit 14%

Als u wilt resulteren in een andere dataset:

df.drop_duplicates(keep=False)

of

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

Als dezelfde dataset moet worden bijgewerkt:

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

Bovenstaande voorbeelden zullen alle duplicaten verwijderen en onderhouden, vergelijkbaar met DISTINCT *in SQL


Antwoord 4, Autoriteit 5%

Gebruik groupbyEN filter

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)

Antwoord 5, Autoriteit 3%

DRUK-rijen 0 en 1 vereisen alleen (eventuele opmerkingen die overeenkomen met A en C worden bewaard.):

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]

Maar ik vermoed wat je echt wilt is dit (een observatie die overeenkomt met A en C wordt bewaard.):

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]

EDIT:

Nu is het veel duidelijker, daarom:

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]

Antwoord 6, Autoriteit 2%

Probeer deze verschillende dingen

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

of

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

of

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

Other episodes