使用pandas groupby

时间:2017-01-01 11:11:39

标签: python pandas group-by

我有以下表格的数据:

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

我确定有一种方法可以更干净地完成这项工作并且不使用循环,但我似乎无法解决这个问题。任何帮助将不胜感激。

4 个答案:

答案 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 stackvalue_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