使用groupby计算重复的平均值

时间:2013-02-21 19:21:55

标签: python pandas

我有以下形式的实验数据,其中每个实验和治疗一式两份,命中是与特定事件相关的基因:

experiment  treatment   replicate   hit
1   1   1   gene1
1   1   1   gene2
1   1   1   gene1
1   1   1   gene1
1   1   2   gene1
1   1   2   gene1
1   2   1   gene1
1   2   1   gene2
1   2   2   gene2
1   2   2   gene2

我想要做的是计算治疗中每个基因的平均数。

我可以使用value_counts()得出每个实验的基因计数:

counts = df['hit'].groupby([df['experiment'], df['treatment'],
                            df['replicate']]
                          ).value_counts().unstack()

产生如下输出:

experiment  treatment   replicate    gene1  gene2
1   1   1   3   1
1   1   2   2   NA
1   2   1   1   1
1   2   2   NA  2

但我真正想要的是每次治疗的平均计数,所以(假设将NA替换为0):

experiment  treatment   gene1   gene2
1   1   2.5 0.5
1   2   0.5 1.5

有什么想法吗?将.mean()应用于value_counts似乎可以计算出所有列的平均值,而不是每个复制列。

2 个答案:

答案 0 :(得分:0)

只需拿走你的桌子并做另一个小组:

>>> g = d.hit.groupby([d.experiment, d.treatment, d.replicate]).value_counts().unstack().reset_index()
>>> print g
   experiment  treatment  replicate  gene1  gene2
0           1          1          1      3      1
1           1          1          2      2    NaN
2           1          2          1      1      1
3           1          2          2    NaN      2
>>> print g.fillna(0).groupby(['experiment', 'treatment']).mean()
                      replicate  gene1  gene2
experiment treatment                         
1          1                1.5    2.5    0.5
           2                1.5    0.5    1.5

你会得到一个额外无意义的列,它是复制数字的平均值,但你可以把它扔掉。

答案 1 :(得分:0)

您还可以使用被低估的pd.get_dummies

In [31]: pd.get_dummies(df.hit)
Out[31]:
   gene1  gene2
0      1      0
1      0      1
2      1      0
3      1      0
4      1      0
5      1      0
6      1      0
7      0      1
8      0      1
9      0      1

In [32]: df2 = pd.get_dummies(df.hit).groupby([df.experiment,df.treatment,df.replicate]).sum(); df2
Out[32]:
                                gene1  gene2
experiment treatment replicate
1          1         1              3      1
                     2              2      0
           2         1              1      1
                     2              0      2

In [34]: df2.groupby(level='treatment').mean()
Out[34]:
           gene1  gene2
treatment
1            2.5    0.5
2            0.5    1.5