Python Pandas中R的tapply()的等价物

时间:2014-01-03 14:21:14

标签: python r pandas tapply

我有一个数据集,其中包含3只动物的喂养数据,包括动物的标签ID(1,2,3),每种膳食给出的饲料类型(A,B)和数量(kg) ':

Animal   FeedType   Amount(kg)
Animal1     A         10
Animal2     B         7
Animal3     A         4
Animal2     A         2
Animal1     B         5
Animal2     B         6
Animal3     A         2

在基数R中,我可以轻松输出下面的矩阵,其中unique('Animal')为行,unique('FeedType')为列,矩阵的相应单元格中的累积Amount (kg) tapply()如下所示

out <- with(mydf, tapply(Amount, list(Animal, FeedType), sum))

         A  B
Animal1 10  5
Animal2  2 13
Animal3  6 NA

Python Pandas数据帧是否有相同的功能?在熊猫中实现这一目标的最优雅,最快捷的方式是什么?

P.S。我希望能够指定哪个列(在本例中为Amount)来执行聚合。

提前致谢。

修改

我在两个答案中尝试了两种方法。性能结果与我的实际Pandas数据框架216,347行和15列:

start_time1 = timeit.default_timer()
mydf.groupby(['Animal','FeedType'])['Amount'].sum()
elapsed_groupby = timeit.default_timer() - start_time1

start_time2 = timeit.default_timer()
mydf.pivot_table(rows='Animal', cols='FeedType',values='Amount',aggfunc='sum')
elapsed_pivot = timeit.default_timer() - start_time2

print ('elapsed_groupby: ' + str(elapsed_groupby))
print ('elapsed_pivot: ' + str(elapsed_pivot))

给出:

elapsed_groupby: 10.172213
elapsed_pivot: 8.465783

所以在我的情况下,pivot_table()工作得更快。

2 个答案:

答案 0 :(得分:7)

首先我读了你的数据:

In [7]: df = pd.read_clipboard(sep="\s+", index_col=False)

In [8]: df
Out[8]:
    Animal FeedType  Amount(kg)
0  Animal1        A          10
1  Animal2        B           7
2  Animal3        A           4
3  Animal2        A           2
4  Animal1        B           5
5  Animal2        B           6
6  Animal3        A           2

然后我可以将两列分组聚合:

In [9]: df.groupby(['Animal','FeedType']).sum()
Out[9]:
                  Amount(kg)
Animal  FeedType
Animal1 A                 10
        B                  5
Animal2 A                  2
        B                 13
Animal3 A                  6

要以相同的格式获取,我可以unstack dataframe

In [10]: df.groupby(['Animal','FeedType']).sum().unstack()
Out[10]:
          Amount(kg)
FeedType           A   B
Animal
Animal1           10   5
Animal2            2  13
Animal3            6 NaN

答案 1 :(得分:5)

@ Zelazny7与groupbyunstack的方法当然没问题,但为了完整起见,您也可以直接使用pivot_table执行此操作(请参阅doc)[version 0.13及以下]:

In [13]: df.pivot_table(rows='Animal', cols='FeedType', values='Amount(kg)', aggfunc='sum')
Out[13]:
FeedType   A   B
Animal
Animal1   10   5
Animal2    2  13
Animal3    6 NaN

在较新版本的Pandas(版本0.14及后者)中,pivot_table的参数已更改:

In [13]: df.pivot_table(index='Animal', columns='FeedType', values='Amount(kg)', aggfunc='sum')
Out[13]:
FeedType   A   B
Animal
Animal1   10   5
Animal2    2  13
Animal3    6 NaN