我有以下表格的数据:
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
组内的非空值始终相同。我想为每个组(它存在的位置)计算一次非空值,然后查找每个值的总计数。
我目前正在以下(笨重和低效)的方式做这件事:
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
我确定有一种方法可以更干净地完成这项工作并且不使用循环,但我似乎无法解决这个问题。任何帮助将不胜感激。
答案 0 :(得分:31)
我认为您可以使用SeriesGroupBy.nunique
:
print (df.groupby('param')['group'].nunique())
param
a 2
b 1
Name: group, dtype: int64
使用unique
的另一个解决方案,然后按DataFrame.from_records
创建新的df
,重新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
答案 1 :(得分:13)
这只是解决方案的附加组件,以防您不仅要计算唯一值而且要计算其他聚合函数:
df.groupby(['group']).agg(['min','max','count','nunique'])
希望你觉得它很有用
答案 2 :(得分:9)
我知道自从发布以来已经有一段时间了,但是我认为这也会有所帮助。 我想计算唯一值并按这些唯一值的数量过滤组,这就是我的方法:
df.groupby('group').agg(['min','max','count','nunique']).reset_index(drop=False)
答案 3 :(得分:1)
上述答案也适用,但如果您想向现有数据框中添加带有 unique_counts 的列,您可以使用 transform
df['distinct_count'] = df.groupby(['param'])['group'].transform('nunique')
输出:
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
并检查@jezrael 高的组数。
print (df.groupby('param')['group'].nunique())
param
a 2
b 1
Name: group, dtype: int64