Pandas分组聚合:计数和平均值的结合

54

使用pandas尝试将数据框汇总为特定类别的计数以及这些类别的平均情感分数。

有一张表格,其中包含具有不同情感分数的字符串,并且我想通过指出它们有多少篇文章来对每个文本来源进行分组,以及这些文章的平均情感。

我的(简化后的)数据框如下:

source    text              sent
--------------------------------
bar       some string       0.13
foo       alt string        -0.8
bar       another str       0.7
foo       some text         -0.2
foo       more text         -0.5

这应该输出类似于这样的结果:

source    count     mean_sent
-----------------------------
foo       3         -0.5
bar       2         0.415

答案大致是这样的:

df['sent'].groupby(df['source']).mean()

然而只给出每个来源及其平均值,没有列标题。

6个回答

66

您可以使用groupbyaggregate操作:

df = df.groupby('source') \
       .agg({'text':'size', 'sent':'mean'}) \
       .rename(columns={'text':'count','sent':'mean_sent'}) \
       .reset_index()
print (df)
  source  count  mean_sent
0    bar      2      0.415
1    foo      3     -0.500

2
很好的答案。如果您想要计算同一列的计数和平均值,该如何做呢?因为如果您两次传递列名,就会出现重复键错误。 - Yu Chen
4
好的,您可以使用以下代码:df1 = (df.groupby('source')['your column'].agg(('count', 'size'), ('avg', 'mean')).reset_index())。这行代码会按照“source”列的值对数据框进行分组,并对“your column”列计算计数、大小、均值三种统计量,最后重置索引并返回结果。 - jezrael
1
我有几个变量在我的数据集中,我只想要这些变量的平均值,并且我只想要按照分组变量进行计数。有没有办法做到这一点? - JodeCharger100

31

在更新版本的pandas中,您不再需要使用rename,只需使用命名聚合即可:

df = df.groupby('source') \
       .agg(count=('text', 'size'), mean_sent=('sent', 'mean')) \
       .reset_index()

print (df)
  source  count  mean_sent
0    bar      2      0.415
1    foo      3     -0.500

1
我有几个变量在我的数据集中,我只想要这些变量的平均值,并且我只想要按照分组变量进行计数。有没有办法做到这一点? - JodeCharger100
@JyothsnaHarithsa 你可能需要构建一个键值对字典:(元组) 并使用 **kdict 传递它。如果你这样做两次,你的代码可能会更清晰。 - neves
@JodeCharger100 你可以使用 groupby.transform 函数并加上 size 参数来获取计数,然后再调用 groupby.mean 函数:df['size'] = df.groupby('group_var').transform('size') mean_df = df.groupby('group_var').mean() - The Authors

16

以下的代码应该能正常工作:

df[['source','sent']].groupby('source').agg(['count','mean'])

2
一个更简短的实现方式是:

df.groupby('source')['sent'].agg(count='size', mean_sent='mean').reset_index()

这个好处是,如果你想要计算多个变量的平均值,但只想计数一次,你可以进行扩展。在这种情况下,你需要传递一个字典:
df.groupby('source')['sent1', 'sent2'].agg({'count': 'size', 'means': 'mean'}).reset_index()

1

对于那些正在寻找超过两列的聚合(就像我一样):只需将它们添加到“agg”即可。

df = df.groupby(['id']).agg({'texts': 'size', 'char_num': 'mean', 'bytes': 'mean'}).reset_index()

-1
我认为这应该提供您想要的输出:
result = pd.DataFrame(df.groupby('source').size())

results['mean_score'] =  df.groupby('source').sent.mean()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接