我正在尝试找出将函数应用于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
>>>
这是最好的方法吗?他们的方法是否需要重置数据帧索引?
答案 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'。