NBF*_*NBF 7 python python-itertools pandas functools
我想以类似于它们在带有列表的本机 python 中应用的方式在 Pandas 中使用reduce和accumulate函数。在itertools 和functools 实现中,reduce 和accumulate(在其他语言中有时称为fold 和cumulative fold)需要一个带有两个参数的函数。在 Pandas 中,没有类似的实现。该函数有两个参数:f(accumulated_value,popped_value)
所以,我有一个二进制变量列表,并想计算我们处于 1 状态时的持续时间数:
In [1]: from itertools import accumulate
import pandas as pd
drawdown_periods = [0,1,1,1,0,0,0,1,1,1,1,0,1,1,0]
Run Code Online (Sandbox Code Playgroud)
使用 lambda 函数将累积应用于此
lambda x,y: (x+y)*y
Run Code Online (Sandbox Code Playgroud)
给
In [2]: list(accumulate(drawdown_periods, lambda x,y: (x+y)*y))
Out[2]: [0, 1, 2, 3, 0, 0, 0, 1, 2, 3, 4, 0, 1, 2, 0]
Run Code Online (Sandbox Code Playgroud)
计算每个 drawdown_period 的长度。
有没有一种聪明但古怪的方法来提供带有两个参数的 lambda 函数?我可能在这里错过了一个技巧。
我知道 groupby 有一个可爱的配方(参见StackOverflow 如何计算 Pandas 中的连续相等值/如何使用 series/dataframe 模拟 itertools.groupby)。我会重复一遍,因为它太可爱了:
In [3]: df = pd.DataFrame(data=drawdown_periods, columns=['dd'])
df['dd'].groupby((df['dd'] != df['dd'].shift()).cumsum()).cumsum()
Out[3]:
0 0
1 1
2 2
3 3
4 0
5 0
6 0
7 1
8 2
9 3
10 4
11 0
12 1
13 2
14 0
Name: dd, dtype: int64
Run Code Online (Sandbox Code Playgroud)
这不是我想要的解决方案。我需要一种将两个参数的 lambda 函数传递给 Pandas 原生的 reduce/accumulate 函数的方法,因为这也适用于许多其他函数式编程方法。
您可以使用 来使其工作,但会降低效率numpy
。在实践中,您可能会更好地编写临时矢量化解决方案。
使用np.frompyfunc
:
s = pd.Series([0,1,1,1,0,0,0,1,1,1,1,0,1,1,0])
f = numpy.frompyfunc(lambda x, y: (x+y) * y, 2, 1)
f.accumulate(series.astype(object))
0 0
1 1
2 2
3 3
4 0
5 0
6 0
7 1
8 2
9 3
10 4
11 0
12 1
13 2
14 0
dtype: object
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6539 次 |
最近记录: |