294 votes

Compter les valeurs uniques avec pandas par groupes

J'ai besoin de compter les valeurs uniques de ID dans chaque domaine J'ai des données

ID, domaine
123, 'vk.com'
123, 'vk.com'
123, 'twitter.com'
456, 'vk.com'
456, 'facebook.com'
456, 'vk.com'
456, 'google.com'
789, 'twitter.com'
789, 'vk.com'

J'essaie df.groupby(['domaine', 'ID']).count() Mais je veux obtenir

domaine, count
vk.com   3
twitter.com   2
facebook.com   1
google.com   1

363voto

jezrael Points 290608

Vous avez besoin de nunique:

df = df.groupby('domain')['ID'].nunique()

print (df)
domain
'facebook.com'    1
'google.com'      1
'twitter.com'     2
'vk.com'          3
Name: ID, dtype: int64

Si vous avez besoin de strip les caractères ':

df = df.ID.groupby([df.domain.str.strip("'")]).nunique()
print (df)
domain
facebook.com    1
google.com      1
twitter.com     2
vk.com          3
Name: ID, dtype: int64

Ou comme Jon Clements a commenté:

df.groupby(df.domain.str.strip("'"))['ID'].nunique()

Vous pouvez conserver le nom de la colonne comme ceci:

df = df.groupby(by='domain', as_index=False).agg({'ID': pd.Series.nunique})
print(df)
    domain  ID
0       fb   1
1      ggl   1
2  twitter   2
3       vk   3

La différence est que nunique() retourne une Series et agg() retourne un DataFrame.

0 votes

Étrange, mais selon mes données, cela renvoie la quantité de tous les domaines, et non d'utilisateurs uniques

0 votes

Intéressant, cela fonctionne bien avec un exemple et non avec des données réelles ?

0 votes

df.groupby(df.domain.str.strip("'"))['ID'].nunique() retourne correct, mais df = df.groupby('domain')['ID'].nunique() non

304voto

Psidom Points 115100

Généralement pour compter les valeurs distinctes dans une seule colonne, vous pouvez utiliser Series.value_counts:

df.domain.value_counts()

#'vk.com'          5
#'twitter.com'     2
#'facebook.com'    1
#'google.com'      1
#Name: domain, dtype: int64

Pour voir combien de valeurs uniques dans une colonne, utilisez Series.nunique:

df.domain.nunique()
# 4

Pour obtenir toutes ces valeurs distinctes, vous pouvez utiliser unique ou drop_duplicates, la légère différence entre les deux fonctions est que unique renvoie un numpy.array tandis que drop_duplicates renvoie un pandas.Series:

df.domain.unique()
# array(["'vk.com'", "'twitter.com'", "'facebook.com'", "'google.com'"], dtype=object)

df.domain.drop_duplicates()
#0          'vk.com'
#2     'twitter.com'
#4    'facebook.com'
#6      'google.com'
#Name: domain, dtype: object

Quant à ce problème spécifique, puisque vous souhaitez compter une valeur distincte par rapport à une autre variable, en plus de la méthode groupby fournie par d'autres réponses ici, vous pouvez également simplement supprimer les doublons d'abord et ensuite utiliser value_counts():

import pandas as pd
df.drop_duplicates().domain.value_counts()

# 'vk.com'          3
# 'twitter.com'     2
# 'facebook.com'    1
# 'google.com'      1
# Name: domain, dtype: int64

61voto

kamran kausar Points 311

Df.domain.value_counts()

>>> df.domain.value_counts()
vk.com          5
twitter.com     2
google.com      1
facebook.com    1
Name: domain, dtype: int64

0 votes

Df.isnull().any(axis=1).value_counts()

14voto

ysearka Points 2280

Si vous voulez le nombre différent d'ID pour chaque domaine, vous pouvez essayer ceci :

output = df.drop_duplicates()
output.groupby('domain').size()

Résultat :

    domaine
facebook.com    1
google.com      1
twitter.com     2
vk.com          3
dtype: int64

Vous pouvez également utiliser value_counts, qui est légèrement moins efficace. Mais le meilleur est la réponse de Jezrael en utilisant nunique :

%timeit df.drop_duplicates().groupby('domain').size()
1000 boucles, meilleure de 3 : 939 µs par boucle
%timeit df.drop_duplicates().domain.value_counts()
1000 boucles, meilleure de 3 : 1,1 ms par boucle
%timeit df.groupby('domain')['ID'].nunique()
1000 boucles, meilleure de 3 : 440 µs par boucle

2 votes

Value_counts est légèrement plus rapide sur un dataframe plus grand : i.imgur.com/V8kcVb8.png

0 votes

@ayhan J'aurais dû essayer sur des dataframes plus grands, c'est de ma faute. Merci de l'avoir souligné!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X