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

如何在不插值无交易行的情况下计算后续行的VWAP

解决VWAP计算中无交易时段导致后续值为NaN的问题

当交易数据存在无交易时段(对应行Volume为0,High/Low/Close为NaN)时,原有的VWAP计算代码会在遇到第一个NaN后,后续所有行的VWAP都变为NaN。我们需要保留无交易行用于图表展示,同时正常计算后续有交易行的VWAP,且不填充无交易行的其他列值。

原代码

import pandas as pd
import numpy as np

data = [
    {'Volume': 1000, 'Open': 1, 'High':1.1, 'Low':0.5, 'Close':1.05},
    {'Volume': 1000, 'Open': 2, 'High':2.1, 'Low':0.6, 'Close':2.05},
    {'Volume': 1000, 'Open': 3, 'High':3.1, 'Low':0.7, 'Close':3.05},
    {'Volume': 0, 'Open': None, 'High':None, 'Low':None, 'Close':None},
    {'Volume': 1000, 'Open': 4, 'High':4.1, 'Low':0.8, 'Close':4.05},
    {'Volume': 1000, 'Open': 5, 'High':5.1, 'Low':0.9, 'Close':5.05}
]

df = pd.DataFrame(data)

v = df['Volume'].values
h = df['High'].values
l = df['Low'].values
c = df['Close'].values

df['vwap'] = np.cumsum(v*(h+l+c)/3) / np.cumsum(v)

print(df)

原输出

Volume  Open  High  Low  Close      vwap
0    1000   1.0   1.1  0.5   1.05  0.883333
1    1000   2.0   2.1  0.6   2.05  1.233333
2    1000   3.0   3.1  0.7   3.05  1.583333
3       0   NaN   NaN  NaN    NaN       NaN
4    1000   4.0   4.1  0.8   4.05       NaN
5    1000   5.0   5.1  0.9   5.05       NaN

解决方案

核心思路是仅在有交易的行上计算VWAP,再将结果映射回原DataFrame,避免无交易行的NaN污染累计计算。具体步骤:

  1. 标记出有交易的行(Volume > 0 或 Close 非NaN)
  2. 在筛选出的子数据集上计算累计成交量加权价格和累计成交量
  3. 把计算得到的VWAP值回填到原DataFrame的对应位置,无交易行保持NaN

修改后的代码

import pandas as pd
import numpy as np

data = [
    {'Volume': 1000, 'Open': 1, 'High':1.1, 'Low':0.5, 'Close':1.05},
    {'Volume': 1000, 'Open': 2, 'High':2.1, 'Low':0.6, 'Close':2.05},
    {'Volume': 1000, 'Open': 3, 'High':3.1, 'Low':0.7, 'Close':3.05},
    {'Volume': 0, 'Open': None, 'High':None, 'Low':None, 'Close':None},
    {'Volume': 1000, 'Open': 4, 'High':4.1, 'Low':0.8, 'Close':4.05},
    {'Volume': 1000, 'Open': 5, 'High':5.1, 'Low':0.9, 'Close':5.05}
]

df = pd.DataFrame(data)

# 标记有交易的行
has_trade = df['Volume'] > 0

# 提取有交易的子数据集
trade_df = df[has_trade].copy()

# 在子数据集上计算VWAP
trade_df['price_avg'] = (trade_df['High'] + trade_df['Low'] + trade_df['Close']) / 3
trade_df['cum_vwap_sum'] = np.cumsum(trade_df['Volume'] * trade_df['price_avg'])
trade_df['cum_volume'] = np.cumsum(trade_df['Volume'])
trade_df['vwap'] = trade_df['cum_vwap_sum'] / trade_df['cum_volume']

# 将计算结果回填到原DataFrame
df['vwap'] = trade_df['vwap']

print(df)

输出结果

Volume  Open  High  Low  Close      vwap
0    1000   1.0   1.1  0.5   1.05  0.883333
1    1000   2.0   2.1  0.6   2.05  1.233333
2    1000   3.0   3.1  0.7   3.05  1.583333
3       0   NaN   NaN  NaN    NaN       NaN
4    1000   4.0   4.1  0.8   4.05  2.083333
5    1000   5.0   5.1  0.9   5.05  2.583333

说明

  • 无交易行(第3行)的vwap保持NaN,其他列值也未被修改
  • 后续有交易行(第4、5行)的VWAP正常计算,累计逻辑不受无交易行影响
  • 计算过程中仅处理有交易的数据,避免了NaN对累计求和的干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:05:33