使用pandas groupby计算唯一值

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,然后创建新dfDataFrame.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)

  • @dondapati - 添加`.reset_index()` (2认同)

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)