use*_*046 20 python group-by pandas
我有以下形式的数据:
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
Run Code Online (Sandbox Code Playgroud)
组内的非空值始终相同.我想为每个组(它存在的位置)计算一次非空值,然后查找每个值的总计数.
我目前正在以下(笨重和低效)的方式做到这一点:
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
Run Code Online (Sandbox Code Playgroud)
我确信有一种方法可以更干净地完成这项工作并且不使用循环,但我似乎无法解决这个问题.任何帮助将非常感激.
jez*_*ael 35
我想你可以用SeriesGroupBy.nunique
:
print (df.groupby('param')['group'].nunique())
param
a 2
b 1
Name: group, dtype: int64
Run Code Online (Sandbox Code Playgroud)
有另一种解决方案unique
,然后创建新df
的DataFrame.from_records
,以重塑Series
通过stack
和最后一个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
Run Code Online (Sandbox Code Playgroud)
anu*_*anu 21
上面的答案也有效,但如果您想将具有 unique_counts 的列添加到现有数据框中,您可以使用转换来做到这一点
df['distinct_count'] = df.groupby(['param'])['group'].transform('nunique')
Run Code Online (Sandbox Code Playgroud)
输出:
group param distinct_count
0 1 a 2.0
1 1 a 2.0
2 2 b 1.0
3 3 NaN NaN
4 3 a 2.0
5 3 a 2.0
6 4 NaN NaN
Run Code Online (Sandbox Code Playgroud)
并检查 @jezrael 高的组计数。
print (df.groupby('param')['group'].nunique())
Run Code Online (Sandbox Code Playgroud)
param
a 2
b 1
Name: group, dtype: int64
Run Code Online (Sandbox Code Playgroud)
dat*_*pug 17
这只是解决方案的附加组件,以防您不仅要计算唯一值而且要计算其他聚合函数:
df.groupby(['group']).agg(['min','max','count','nunique'])
Run Code Online (Sandbox Code Playgroud)
希望你觉得它有用
小智 9
我知道这篇文章发布已经有一段时间了,但我认为这也会有所帮助。我想计算唯一值并按这些唯一值的数量过滤组,我是这样做的:
df.groupby('group').agg(['min','max','count','nunique']).reset_index(drop=False)
Run Code Online (Sandbox Code Playgroud)