You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将涨跌成交量计算函数适配到Pandas滚动窗口?

实现滚动50天涨跌成交量比率的方法

核心思路

通过向量化预处理配合滚动窗口求和,替代逐窗口调用自定义函数的方式,既能实现每日的历史比率计算,又能保证计算效率。具体步骤如下:


步骤1:预处理涨跌成交量列

先为DataFrame新增两列,分别标记当日上涨/下跌时的成交量(非涨跌日成交量记为0):

# 计算每日涨跌幅(首行Change为NaN,对应首日无涨跌数据)
df['Change'] = df['Close'].pct_change()

# 上涨日成交量:当日涨跌幅>0时取Volume,否则为0
df['Up_Volume'] = df.apply(lambda x: x['Volume'] if x['Change'] > 0 else 0, axis=1)
# 下跌日成交量:当日涨跌幅<0时取Volume,否则为0
df['Down_Volume'] = df.apply(lambda x: x['Volume'] if x['Change'] < 0 else 0, axis=1)

步骤2:滚动计算50天窗口的成交量总和

使用rolling(50)窗口分别计算上涨、下跌成交量的滚动总和:

# 滚动50天上涨成交量总和
df['Rolling_Up_Vol'] = df['Up_Volume'].rolling(window=50).sum()
# 滚动50天下跌成交量总和
df['Rolling_Down_Vol'] = df['Down_Volume'].rolling(window=50).sum()

步骤3:计算涨跌成交量比率

将两个滚动总和相除,同时处理下跌成交量总和为0的特殊情况(避免除以0错误):

# 计算比率,保留两位小数;若下跌总和为0,设为None(也可自定义其他值)
df['Up_Down_Vol_Ratio'] = df.apply(
    lambda x: round(x['Rolling_Up_Vol'] / x['Rolling_Down_Vol'], 2) 
    if x['Rolling_Down_Vol'] != 0 else None,
    axis=1
)

完整代码示例

# 假设你的DataFrame名为df,包含Close和Volume列
df['Change'] = df['Close'].pct_change()
df['Up_Volume'] = df.apply(lambda x: x['Volume'] if x['Change'] > 0 else 0, axis=1)
df['Down_Volume'] = df.apply(lambda x: x['Volume'] if x['Change'] < 0 else 0, axis=1)

df['Rolling_Up_Vol'] = df['Up_Volume'].rolling(window=50).sum()
df['Rolling_Down_Vol'] = df['Down_Volume'].rolling(window=50).sum()

df['Up_Down_Vol_Ratio'] = df.apply(
    lambda x: round(x['Rolling_Up_Vol'] / x['Rolling_Down_Vol'], 2) if x['Rolling_Down_Vol'] != 0 else None,
    axis=1
)

# 查看最近20天的计算结果
print(df[['Close', 'Volume', 'Up_Down_Vol_Ratio']].tail(20))

效率说明

直接用rolling.apply调用原自定义函数虽然可行,但逐窗口处理的效率极低(数据量大时尤为明显)。上述向量化+滚动求和的方式利用Pandas内置优化,计算速度会提升数倍甚至数十倍。


内容的提问来源于stack exchange,提问作者RazzleDazzle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:27:34