Supprimez toutes les lignes en double dans Python Pandas

160

La pandas drop_duplicatesfonction est idéale pour «uniquifier» une trame de données. Cependant, l'un des arguments de mot-clé à passer est take_last=Trueou take_last=False, alors que je voudrais supprimer toutes les lignes qui sont en double dans un sous-ensemble de colonnes. Est-ce possible?

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

À titre d'exemple, je voudrais supprimer les lignes qui correspondent aux colonnes A, Cce qui devrait supprimer les lignes 0 et 1.

Jamie Bull
la source

Réponses:

235

C'est beaucoup plus facile dans les pandas maintenant avec drop_duplicates et le paramètre 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
la source
2
Que faire si mes colonnes ne sont pas explicitement étiquetées? Comment sélectionner les colonnes uniquement en fonction de leur index?
Hamman Samuel
2
Peut df.reindex(df.iloc[:,[0,2]].drop_duplicates(keep=False).index)- être ?
Ben
5
vous pourriez essayerdf.drop_duplicates(subset=[df.columns[0:2]], keep = False)
seeiespi
69

Je veux juste ajouter à la réponse de Ben sur drop_duplicates :

keep : {'first', 'last', False}, par défaut 'first'

  • first: supprime les doublons sauf pour la première occurrence.

  • last: supprime les doublons à l'exception de la dernière occurrence.

  • Faux: supprime tous les doublons.

Ainsi, définir keepsur False vous donnera la réponse souhaitée.

DataFrame.drop_duplicates (* args, ** kwargs) Renvoie le DataFrame avec les lignes en double supprimées, éventuellement en ne considérant que certaines colonnes

Paramètres: sous-ensemble: étiquette de colonne ou séquence d'étiquettes, facultatif Ne considérer que certaines colonnes pour identifier les doublons, par défaut utiliser toutes les colonnes keep: {'first', 'last', False}, default 'first' first: Supprimer les doublons sauf pour la première occurrence. last: supprime les doublons à l'exception de la dernière occurrence. Faux: supprime tous les doublons. take_last: obsolète en place: booléen, par défaut False S'il faut supprimer les doublons sur place ou renvoyer une copie cols: kwargs uniquement argument du sous-ensemble [obsolète] Renvoie: dédupliqué: DataFrame

Jake
la source
26

Si vous souhaitez que le résultat soit stocké dans un autre ensemble de données:

df.drop_duplicates(keep=False)

ou

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

Si le même ensemble de données doit être mis à jour:

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

Les exemples ci-dessus supprimeront tous les doublons et en conserveront un, comme DISTINCT *dans SQL

Ramanujam Allam
la source
12

utiliser groupbyetfilter

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
la source
5

En fait, supprimer les lignes 0 et 1 nécessite uniquement (toutes les observations contenant A et C correspondants sont conservées.):

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]

Mais je suppose que ce que vous voulez vraiment est ceci (une observation contenant A et C correspondants est conservée.):

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]

Éditer:

Maintenant, c'est beaucoup plus clair, donc:

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
la source
1
Si c'était ce que je voulais, je n'utiliserais df.drop_duplicates(['A','C'])que par défaut, garder une observation prendre la première ou la dernière comme je l'ai mentionné dans la question - bien que je viens de réaliser que j'avais le mot-clé incorrect alors que j'écrivais de mémoire. Ce que je veux, c'est supprimer toutes les lignes identiques sur les colonnes d'intérêt (A et C dans les données d'exemple).
Jamie Bull
0

Essayez ces différentes choses

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

ou

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

ou

>>>df.drop_duplicates( keep='last')
Priyansh gupta
la source