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.
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
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