Comment «sélectionner distinct» sur plusieurs colonnes de trame de données dans les pandas?


104

Je cherche un moyen de faire l'équivalent du SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

La comparaison pandas sql n'a rien à propos de distinct.

.unique() ne fonctionne que pour une seule colonne, donc je suppose que je pourrais concaténer les colonnes, ou les mettre dans une liste / tuple et comparer de cette façon, mais cela semble être quelque chose que les pandas devraient faire de manière plus native.

Est-ce que je manque quelque chose d'évident ou n'y a-t-il aucun moyen de le faire?


Vous auriez à faire quelque chose comme, df.apply(pd.Series.unique)mais cela ne fonctionnera pas si le nombre de valeurs uniques varie d'une colonne à l'autre, vous devrez donc construire un dict des noms de colonnes en tant que clés et des valeurs uniques en tant que valeurs
— EdChum

Réponses:


175

Vous pouvez utiliser la drop_duplicatesméthode pour obtenir les lignes uniques dans un DataFrame:

In [29]: df = pd.DataFrame({'a':[1,2,1,2], 'b':[3,4,3,5]})

In [30]: df
Out[30]:
   a  b
0  1  3
1  2  4
2  1  3
3  2  5

In [32]: df.drop_duplicates()
Out[32]:
   a  b
0  1  3
1  2  4
3  2  5

Vous pouvez également fournir l' subsetargument mot - clé si vous souhaitez utiliser uniquement certaines colonnes pour déterminer l'unicité. Voir la docstring .


5
Il est peut-être intéressant de noter que, df.drop_duplicates()par défaut, ce n'est pas une méthode inplace, donc renvoie un nouveau DataFrame (en laissant dfinchangé). C'est un comportement assez standard, mais qui peut encore être utile.
— evophage

14

J'ai essayé différentes solutions. Le premier était:

a_df=np.unique(df[['col1','col2']], axis=0)

et cela fonctionne bien pour les données non-objet Une autre façon de faire cela et d'éviter les erreurs (pour le type de colonnes objet) est d'appliquer drop_duplicates ()

a_df=df.drop_duplicates(['col1','col2'])[['col1','col2']]

Vous pouvez également utiliser SQL pour ce faire, mais cela a fonctionné très lentement dans mon cas:

from pandasql import sqldf
q="""SELECT DISTINCT col1, col2 FROM df;"""
pysqldf = lambda q: sqldf(q, globals())
a_df = pysqldf(q)

7

Il n'y a pas de uniqueméthode pour un df, si le nombre de valeurs uniques pour chaque colonne était le même, alors ce qui suit fonctionnerait: df.apply(pd.Series.unique)mais sinon, vous obtiendrez une erreur. Une autre approche serait de stocker les valeurs dans un dict qui est indexé sur le nom de la colonne:

In [111]:
df = pd.DataFrame({'a':[0,1,2,2,4], 'b':[1,1,1,2,2]})
d={}
for col in df:
    d[col] = df[col].unique()
d

Out[111]:
{'a': array([0, 1, 2, 4], dtype=int64), 'b': array([1, 2], dtype=int64)}

est-il possible de vérifier le caractère unique de plusieurs colonnes?
— Anoop D

J'ai obtenu la réponse à une autre question SO en utilisant numpynp.unique(df[['column1','column2']].values)
— Anoop D

6

Pour résoudre un problème similaire, j'utilise groupby:

print(f"Distinct entries: {len(df.groupby(['col1', 'col2']))}")

Cependant, si cela est approprié dépendra de ce que vous voulez faire avec le résultat (dans mon cas, je voulais juste l'équivalent de COUNT DISTINCTcomme indiqué).



-1

Vous pouvez prendre les ensembles de colonnes et simplement soustraire le plus petit ensemble du plus grand ensemble:

distinct_values = set(df['a'])-set(df['b'])
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.