在数据框上应用扩展功能

时间:2020-01-19 12:07:26

标签: python pandas dataframe

我有一个函数希望应用于pandas DataFrame的子集,因此该函数是在同一组的所有行(直到当前行)上计算的,即使用groupby然后使用{ {1}}。

例如,此数据框:

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

[为清晰起见,根据jezrael的反馈进行了编辑:我的实际功能更加复杂,因此无法轻松分解为该任务的组件。这个简单的功能仅适用于MCVE。]

我想做类似的事情: def foo(_df): return _df['x1'].max() * _df['x2'].iloc[-1]

要获得此结果:

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 会导致df.groupby('group').expanding().apply(foo, raw=False)

是否有正确的方法来运行此程序,或者在KeyError: 'x1'中不将我的功能分解为组件而无法运行?

2 个答案:

答案 0 :(得分:1)

可能的解决方案是使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数据框的问题的直接解决方案,但是它实现了相同的功能。

答案 1 :(得分:0)

显然无法在expanding窗口上应用数据框函数(至少对于非熊猫版本0.23.0),如将print语句插入函数中所看到的那样。

在给定的DataFrame上运行df.groupby('group').expanding().apply(lambda x: bool(print(x)) , raw=False)(其中bool周围的print只是为了获得有效的返回值)返回:

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函数中,就像在接受的答案中一样。