使用Pandas groupby计算许多斜率

时间:2015-04-27 22:32:44

标签: pandas

DataFrame(MultiIndex)格式的一些说明性数据:

|entity| year |value| +------+------+-----+ | a | 1999 | 2 | | | 2004 | 5 | | b | 2003 | 3 | | | 2007 | 2 | | | 2014 | 7 |

我想在上例中为每个实体scipy.stats.linregressa使用b计算斜率。我尝试在split-apply-combine advice之后的第一列使用groupby,但似乎有问题,因为它期待一个Series的值a和{{1但是我需要对右边的两列进行操作。

这可以通过b在R中轻松完成,不知道如何在熊猫中接近它。

2 个答案:

答案 0 :(得分:5)

可以使用groupby函数将函数应用于apply。在这种情况下传递的函数linregress。请参阅以下内容:

In [4]: x = pd.DataFrame({'entity':['a','a','b','b','b'],
                          'year':[1999,2004,2003,2007,2014],
                          'value':[2,5,3,2,7]})

In [5]: x
Out[5]: 
  entity  value  year
0      a      2  1999
1      a      5  2004
2      b      3  2003
3      b      2  2007
4      b      7  2014


In [6]: from scipy.stats import linregress

In [7]: x.groupby('entity').apply(lambda v: linregress(v.year, v.value)[0])
Out[7]: 
entity
a    0.600000
b    0.403226

答案 1 :(得分:3)

您可以通过按对象分组的迭代器功能来完成此操作。通过删除当前索引然后通过'entity'指定组来实现它似乎更容易。

然后,列表理解是一种快速处理迭代器中所有组的简单方法。或者使用字典理解将标签放在同一个地方(然后你可以轻松地将字典粘贴到pd.DataFrame中)。

import pandas as pd
import scipy.stats

#This is your data
test = pd.DataFrame({'entity':['a','a','b','b','b'],'year':[1999,2004,2003,2007,2014],'value':[2,5,3,2,7]}).set_index(['entity','year'])

#This creates the groups
groupby = test.reset_index().groupby(['entity'])

#Process groups by list comprehension
slopes = [scipy.stats.linregress(group.year, group.value)[0] for name, group in groupby]
#Process groups by dict comprehension
slopes = {name:[scipy.stats.linregress(group.year, group.value)[0]] for name, group in groupby}