在pandas中执行groupby后的计算?

时间:2017-06-07 18:27:18

标签: python pandas dataframe pandas-groupby

我有以下带有四列的数据框(我已将其简化,并且它也更长)。用户权重始终为1,因此他们的响应被平等对待。虽然在此示例中为每个帖子分配了相同的三个用户,但实际上用户被随机分配到帖子,并且每个帖子具有分配给它的可变数量的用户。

Post      userid     Weight  Response
-----     --------    ------  ---------
text1      A           1        0
text2      A           1        1
text1      B           1        0
text2      C           1        1
text1      C           1        1
text2      B           1        0

我希望在按帖子分组后,结果数据框看起来如下所示。平均响应只是平均用户'通过邮寄回复(因此,如果0表示错误,1表示真实,那么这将基本上衡量用户声称帖子的真实或错误)。第二列表示协议(因此1是完全一致的,分数越高越好)。

Post      Avg_Response     Agreement
-----     ------------     ---------
text1       0.33            0.66
text2       0.66            0.66

我对如何计算平均响应(使用平均函数)充满信心,但我不确定如何计算协议(最后一列使用pandas。我确信有一些简单的技巧可以在一个两条线。我的猜测是计算每个帖子的0和1的数量除以该分数的响应总数。然后我们将采用更大的比率。如果它们相等,那么我们摆脱它们(所以我们不想要任何用户均分的帖子。)

我非常感谢代码的帮助!谢谢。

2 个答案:

答案 0 :(得分:1)

这是一种方法:

import pandas as pd
import numpy as np
from io import StringIO

df = pd.read_fwf(StringIO("""
Post      userid     Weight  Response
text1      A           1        0
text2      A           1        1
text1      B           1        0
text2      C           1        1
text1      C           1        1
text2      B           1        0
"""), header=1)

mn = df.groupby(['Post'])['Response'].mean()
md = df.groupby(['Post'])['Response'].agg(lambda x: max(np.mean(x), 1 - np.mean(x)))

mn.name = 'Avg_Response'
md.name = 'Agreement'
df2 = pd.concat([mn, md], axis=1)
df2

...屈服

       Avg_Response  Agreement
Post
text1      0.333333   0.666667
text2      0.666667   0.666667

答案 1 :(得分:0)

您可以在不需要pd.concat的情况下执行此操作。使用__name__命名自定义函数,并将它们作为列表传递。

def simple_mean(x):
    return x.mean()

def custom_mean(x):
    return max(x.mean(), 1-x.mean())

simple_mean.__name__ = 'Avg_Response'
custom_mean.__name__ = 'Agreement'

df.groupby('Post')['Response'].agg([simple_mean, custom_mean])

       Avg_Response  Agreement
Post
text1      0.333333   0.666667
text2      0.666667   0.666667