如何在Python/Pandas中基于前10行条件结果生成同行匹配值列表
解决方案
你可以修改rolling.apply中的逻辑,将统计计数改为收集符合条件的具体值列表,关键是把np.sum替换为筛选后的值转列表的操作,同时注意设置raw=False以保留Series的索引信息:
import pandas as pd import numpy as np # 生成测试数据 s = pd.DataFrame(3+np.random.randn(50,2),columns=list('AB')) s['vol'] = pd.Series(np.random.randint(low=5, high=10, size = 50)) s['ub'] = s['B']*1.2 s['lb'] = s['B']*0.8 # 生成符合条件的具体值列表(窗口包含当前行及前9行) s['inrange_values'] = s['B'].rolling(10).apply( lambda x: list(x[(x <= s.loc[x.index.max(), 'B'] * 1.2) & (x >= s.loc[x.index.max(), 'B'] * 0.8)]), raw=False ) # 保留原计数列用于对比 s['inrange_count'] = s['B'].rolling(10).apply(lambda x: np.sum((x<=s.loc[x.index.max(),'B']*1.2) & (x>=s.loc[x.index.max(),'B']*0.8)))
关键细节说明
raw=False:确保传入lambda的x是pandas Series对象,而非numpy数组,这样才能通过x.index.max()获取窗口最后一行的索引,匹配当前行的上下限。- 筛选逻辑:用布尔索引筛选窗口内落在当前行B值80%-120%区间的数值,再转成列表存入新列。
如果你的需求是仅对比当前行的前10行(不包含当前行),可以调整窗口大小并排除当前行,代码如下:
# 仅匹配当前行前10行的版本 s['inrange_values_prev10'] = s['B'].rolling(11).apply( lambda x: list(x[:-1][(x[:-1] <= s.loc[x.index.max(), 'B'] * 1.2) & (x[:-1] >= s.loc[x.index.max(), 'B'] * 0.8)]), raw=False ).shift(1)
内容的提问来源于stack exchange,提问作者Yiwei
相关产品推荐
相关产品推荐

