如何用Pandas筛选Close连续X天高于SMA_10的数据(示例:8天)
问题描述
我创建了如下样本DataFrame,希望筛选出Close列连续X天(本次示例为8天)高于SMA_10列的数据。我了解可以使用close.shift(1)方法,但不想手动编写多个shift条件(如condition = (close.shift(1) > sma10.shift(1)) & close.shift(2)....close.shift(7) > sma10.shift(7)),请问是否有更优实现方式?
示例代码:
import pandas as pd import numpy as np # Generate sample data np.random.seed(123) dates = pd.date_range(start='2022-01-01', periods=100) prices = np.random.rand(100) * 100 sma_10 = pd.Series(prices).rolling(window=10).mean() ohlc_data = np.random.rand(100, 4) * 100 # Create DataFrame df = pd.DataFrame(ohlc_data, columns=['Open', 'High', 'Low', 'Close']) df['Date'] = dates df.loc[9:20, 'Close'] = 80 df['SMA_10'] = sma_10 # Print sample DataFrame print(df.head(20))
最优解决方案
可以通过两步实现,无需手动编写多个shift条件:
- 创建布尔标记列:生成一列布尔值,标记当天
Close是否高于SMA_10 - 滚动窗口统计连续满足条件的天数:使用
rolling窗口对布尔列求和,判断窗口内的和是否等于目标天数(即连续X天都满足条件)
完整实现代码
import pandas as pd import numpy as np # 生成样本数据(和原代码一致) np.random.seed(123) dates = pd.date_range(start='2022-01-01', periods=100) prices = np.random.rand(100) * 100 sma_10 = pd.Series(prices).rolling(window=10).mean() ohlc_data = np.random.rand(100, 4) * 100 df = pd.DataFrame(ohlc_data, columns=['Open', 'High', 'Low', 'Close']) df['Date'] = dates df.loc[9:20, 'Close'] = 80 df['SMA_10'] = sma_10 # 步骤1:创建布尔列,标记当天Close是否大于SMA_10 df['close_above_sma'] = df['Close'] > df['SMA_10'] # 步骤2:设置连续天数X,这里示例为8天 X = 8 # 滚动窗口求和,窗口大小为X,求和结果等于X说明连续X天都满足条件 # 使用shift(1)是标记连续X天结束的那一行,可根据需求调整 df['consecutive_above'] = df['close_above_sma'].rolling(window=X).sum() == X # 筛选出连续8天Close高于SMA_10的行 result = df[df['consecutive_above']] print(result)
补充说明
如果需要筛选出所有处于连续X天区间内的行,可以对标记列做向前填充:
# 先标记连续区间的结束点,再向前填充X-1天的标记 df['in_consecutive_window'] = df['consecutive_above'].replace(False, np.nan).ffill(limit=X-1).fillna(False) result_all_days = df[df['in_consecutive_window']] print(result_all_days)
这种方法的优势是可以灵活调整X值,无需修改条件逻辑,代码可维护性更高。
内容的提问来源于stack exchange,提问作者MasayoMusic
相关产品推荐
相关产品推荐

