将组特定功能应用于Pandas中的组

时间:2015-11-24 23:05:57

标签: python pandas

我正在尝试找出将函数应用于Pandas数据框中的组的最佳方法,其中函数取决于组。

说我有以下数据框:

>>> df=pd.DataFrame(np.random.randint(50,200,9), columns=['Value'])
>>> df['Year']=[2001,2002,2003]*3
>>> df['Location']=['A','A','A','B','B','B','C','C','C']
>>> df.set_index(['Location','Year'], inplace=True)
>>> df
               Value
Location Year       
A        2001    134
         2002    162
         2003    108
B        2001     59
         2002     52
         2003    124
C        2001    148
         2002    162
         2003     66
>>> 

我有以下每年特定的价值字典:

>>> YearDict={2001:1.3, 2002:1.2, 2003:1.1}
>>> YearDict
{2001: 1.3, 2002: 1.2, 2003: 1.1}

将数据框中的“值”列乘以字典中特定年份值的最佳方法是什么?

目前我这样做:

>>> df.reset_index(inplace=True)
>>> def f(row):
...     return row['Value']*YearDict[row['Year']]
... 
>>> 
>>> df.apply(f, axis=1)
0     84.5
1    210.0
2    201.3
3    248.3
4     94.8
5    177.1
6    140.4
7    218.4
8     68.2
dtype: float64
>>> 

这是最好的方法吗?他们的方法是否需要重置数据帧索引?

2 个答案:

答案 0 :(得分:1)

您可以在索引上映射函数。数据框中的每一行都有一个(Location,Year)元组作为索引,因此您可以这样做:

df.index.map(lambda t: YearDict[t[1]])
Out[11]: array([ 1.3,  1.2,  1.1,  1.3,  1.2,  1.1,  1.3,  1.2,  1.1])

因此乘以这些值看起来像:

year_mults = df.index.map(lambda t: YearDict[t[1]])

df['Value'] * year_mults
Out[13]: 
Location  Year
A         2001    247.0
          2002    160.8
          2003    119.9
B         2001    102.7
          2002    182.4
          2003    202.4
C         2001     71.5
          2002    178.8
          2003    211.2
Name: Value, dtype: float64

答案 1 :(得分:1)

看起来我参加聚会有点晚了,但你可以做groupby.transform。例如,在设置索引之前给出原始df:

In [4]: df
Out[4]: 
   Value  Year Loc
0     50  2001   A
1    141  2002   A
2     77  2003   A
3    143  2001   B
4    152  2002   B
5    123  2003   B
6    131  2001   C
7    196  2002   C
8    160  2003   C

In [5]: df.groupby('Year')['Value'].transform(lambda v: v * YearDict[v.name])
Out[5]: 
0     65.0
1    169.2
2     84.7
3    185.9
4    182.4
5    135.3
6    170.3
7    235.2
8    176.0
Name: Value, dtype: float64

这是有效的,因为transform为函数提供了系列的参数以及分组变量的name(在'Year'的值的情况下)。

或者,给定您的DataFrame和MultiIndex,您可以这样做:

In [6]: df2 = df.set_index(['Loc', 'Year'])

In [7]: df2.groupby(level=1).transform(lambda v: v * YearDict[v.name])
Out[7]: 
          Value
Loc Year       
A   2001   65.0
    2002  169.2
    2003   84.7
B   2001  185.9
    2002  182.4
    2003  135.3
C   2001  170.3
    2002  235.2
    2003  176.0

我认为它非常紧凑和可读。 level=1参数表示将MultiIndex的第二级分组,在本例中为'Year'。