如何在 pandas 中的组上滚动应用自定义函数?

How to apply a custom fuction with rolling on groups in pandas?

import pandas as pd
import numpy as np

df = pd.DataFrame.from_dict({'date':[1,2,3,4,5,6,7,8,9,10] ,'open':[4,5,3,4,5,6,7,8,9,10],'close':[4,5,6,7,8,1,2,9,10,11],'stock':['A']*5 + ['B']*5})

df['flag'] = np.select([df['close']>df['open'],df['close']<df['open']],['up','down'],default='flat')
df
date open close stock flag
0 1 4 4 A flat
1 2 5 5 A flat
2 3 3 6 A up
3 4 4 7 A up
4 5 5 8 A up
5 6 6 1 B down
6 7 7 2 B down
7 8 8 9 B up
8 9 9 10 B up
9 10 10 11 B up

我尝试了以下方法。 None 其中有效。他们都给我“没有要聚合的数字类型”错误

# flag if previous 3 days (t-2,t-1, and t) are all increase for each stock

df['3days_up'] = df.groupby('stock')['flag'].rolling(3).apply(lambda x: 'Yes' if all(x['flag']=='up') else 'No')
df['3days_up'] = df.groupby('stock')[['flag']].rolling(3).apply(lambda x: 'Yes' if all(x['flag']=='up') else 'No')
df['3days_up'] = df.groupby('stock').rolling(3).apply(lambda x: 'Yes' if all(x['flag']=='up') else 'No')

预期输出:

date open close stock flag 3days_up
0 1 4 4 A flat No
1 2 5 5 A flat No
2 3 3 6 A up No
3 4 4 7 A up No
4 5 5 8 A up Yes
5 6 6 1 B down No
6 7 7 2 B down No
7 8 8 9 B up No
8 9 9 10 B up No
9 10 10 11 B up Yes

up 值转换为 True 并将其他值转换为 False 作为起点:

df['3days_up'] = np.where(df.assign(is_up=df['flag'] == 'up')
                            .groupby('stock').rolling(3)['is_up']
                            .sum() >= 3, 'Yes', 'No')
print(df)

# Output
   date  open  close stock  flag 3days_up
0     1     4      4     A  flat       No
1     2     5      5     A  flat       No
2     3     3      6     A    up       No
3     4     4      7     A    up       No
4     5     5      8     A    up      Yes
5     6     6      1     B  down       No
6     7     7      2     B  down       No
7     8     8      9     B    up       No
8     9     9     10     B    up       No
9    10    10     11     B    up      Yes