J'ai un dataframe avec 3 colonnes en Python:
Name1 Name2 Value
Juan Ale 1
Ale Juan 1
et souhaite éliminer les doublons en fonction des combinaisons de colonnes Nom1 et Nom2.
Dans mon exemple, les deux lignes sont égales (mais elles sont dans un ordre différent), et je voudrais supprimer la deuxième ligne et simplement conserver la première, donc le résultat final devrait être:
Name1 Name2 Value
Juan Ale 1
Toute idée sera vraiment appréciée!
Vous pouvez convertir en frozenset
et utiliser pd.DataFrame.duplicated
.
res = df[~df[['Name1', 'Name2']].apply(frozenset, axis=1).duplicated()]
print(res)
Name1 Name2 Value
0 Juan Ale 1
frozenset
est nécessaire au lieu de set
car duplicated
utilise le hachage pour vérifier les doublons.
S'adapte mieux aux colonnes qu'aux lignes. Pour un grand nombre de lignes, utilisez l'algorithme basé sur le tri de @ Wen.
En utilisant np.sort
avec duplicated
df[pd.DataFrame(np.sort(df[['Name1','Name2']].values,1)).duplicated()]
Out[614]:
Name1 Name2 Value
1 Ale Juan 1
Performance
df=pd.concat([df]*100000)
%timeit df[pd.DataFrame(np.sort(df[['Name1','Name2']].values,1)).duplicated()]
10 loops, best of 3: 69.3 ms per loop
%timeit df[~df[['Name1', 'Name2']].apply(frozenset, axis=1).duplicated()]
1 loop, best of 3: 3.72 s per loop
Je sais que je suis un peu en retard pour cette question mais je donne quand même ma contribution:)
Vous pouvez aussi utiliser get_dummies
et add
pour une bonne façon de créer des lignes lavables
df[~(pd.get_dummies(df.a).add(pd.get_dummies(df.b), fill_value=0)).duplicated()]
Les temps ne sont pas aussi bons que la réponse de @ Wen, mais ils sont toujours bien plus rapides que apply
+ frozen_set
df=pd.concat([df]*1000000)
%timeit df[~(pd.get_dummies(df.a).add(pd.get_dummies(df.b), fill_value=0)).duplicated()]
1.8 s ± 85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df[pd.DataFrame(np.sort(df[['a','b']].values,1)).duplicated()]
1.26 s ± 19 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df[~df[['a', 'b']].apply(frozenset, axis=1).duplicated()]
1min 9s ± 684 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)