web-dev-qa-db-fra.com

Compter les valeurs uniques en utilisant pandas groupby

J'ai des données de la forme suivante:

df = pd.DataFrame({
    'group': [1, 1, 2, 3, 3, 3, 4],
    'param': ['a', 'a', 'b', np.nan, 'a', 'a', np.nan]
})
print(df)

#    group param
# 0      1     a
# 1      1     a
# 2      2     b
# 3      3   NaN
# 4      3     a
# 5      3     a
# 6      4   NaN

Les valeurs non NULL dans les groupes sont toujours les mêmes. Je veux compter la valeur non nulle pour chaque groupe (s'il existe) une fois, puis trouver le nombre total de comptes pour chaque valeur.

Je le fais actuellement de la manière suivante (maladroite et inefficace):

param = []
for _, group in df[df.param.notnull()].groupby('group'):
    param.append(group.param.unique()[0])
print(pd.DataFrame({'param': param}).param.value_counts())

# a    2
# b    1

Je suis sûr qu'il existe un moyen de le faire plus proprement et sans utiliser de boucle, mais je n'arrive pas à résoudre le problème. Toute aide serait très appréciée.

19
user1684046

Je pense que vous pouvez utiliser SeriesGroupBy.nunique :

print (df.groupby('param')['group'].nunique())
param
a    2
b    1
Name: group, dtype: int64

Une autre solution avec unique , puis créez un nouveau df avec DataFrame.from_records , remodeler en Series par stack et le dernier value_counts :

a = df[df.param.notnull()].groupby('group')['param'].unique()
print (pd.DataFrame.from_records(a.values.tolist()).stack().value_counts())
a    2
b    1
dtype: int64
33
jezrael

Ceci n'est qu'un ajout à la solution dans le cas où vous souhaitez calculer non seulement des valeurs uniques, mais également d'autres fonctions d'agrégat:

df.groupby(['group']).agg(['min','max','count','nunique'])

J'espère que vous le trouverez utile

15
datapug