我有一个函数,我希望将其应用于pandas DataFrame的子集,以便在同一组中的所有行(直到当前行)上计算该函数-即使用groupby,然后使用expanding。
例如,此数据帧:
df = pd.DataFrame.from_dict(
{
'group': ['A','A','A','B','B','B'],
'time': [1,2,3,1,2,3],
'x1': [10,40,30,100,200,300],
'x2': [1,0,1,2,0,3]
}).sort_values('time')即
group time x1 x2
0 A 1 10 1
3 B 1 100 2
1 A 2 40 2
4 B 2 200 0
2 A 3 30 1
5 B 3 300 3和这个函数,例如:
def foo(_df):
return _df['x1'].max() * _df['x2'].iloc[-1]为了清晰起见,根据jezrael的反馈进行了编辑:我的实际功能更复杂,不能很容易地分解为这个任务的组件。这个简单的函数只适用于MCVE。
我想做一些类似的事情:df['foo_result'] = df.groupby('group').expanding().apply(foo, raw=False)
要获得此结果,请执行以下操作:
group time x1 x2 foo_result
0 A 1 10 1 10
3 B 1 100 2 200
1 A 2 40 2 80
4 B 2 200 0 0
2 A 3 30 1 40
5 B 3 300 3 900问题是,在KeyError: 'x1'中运行df.groupby('group').expanding().apply(foo, raw=False)会导致问题。
有没有一种正确的方法来运行它,或者在pandas中不将我的函数分解成组件就不可能做到这一点?
发布于 2020-01-19 20:12:28
一种可能的解决方案是使expanding成为函数的一部分,并使用GroupBy.apply
def foo1(_df):
return _df['x1'].expanding().max() * _df['x2'].expanding().apply(lambda x: x[-1], raw=True)
df['foo_result'] = df.groupby('group').apply(foo1).reset_index(level=0, drop=True)
print (df)
group time x1 x2 foo_result
0 A 1 10 1 10.0
3 B 1 100 2 200.0
1 A 2 40 2 80.0
4 B 2 200 0 0.0
2 A 3 30 1 40.0
5 B 3 300 3 900.0这不是将数据帧函数应用于expanding数据帧问题的直接解决方案,但它实现了相同的功能。
发布于 2020-06-09 15:55:12
在expanding窗口上应用数据帧函数显然是不可能的(至少对于非pandas版本0.23.0),可以通过在函数中插入print语句来看到这一点。
在给定的DataFrame上运行df.groupby('group').expanding().apply(lambda x: bool(print(x)) , raw=False) (其中print周围的bool只是为了获得一个有效的返回值)返回:
0 1.0
dtype: float64
0 1.0
1 2.0
dtype: float64
0 1.0
1 2.0
2 3.0
dtype: float64
0 10.0
dtype: float64
0 10.0
1 40.0
dtype: float64
0 10.0
1 40.0
2 30.0
dtype: float64(以此类推--当然,还会返回每个单元格中包含'0.0‘的数据帧)。
这表明expanding窗口是逐列工作的(我们看到,首先打印展开的time系列,然后打印x1,依此类推),而不是真正在数据帧上工作-因此不能对其应用数据帧函数。
因此,要获得获得的功能,必须将expanding放在dataframe函数中,就像在接受的答案中一样。
https://stackoverflow.com/questions/59809866
复制相似问题