如何在不插值无交易行的情况下计算后续行的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污染累计计算。具体步骤:
- 标记出有交易的行(
Volume > 0或Close非NaN) - 在筛选出的子数据集上计算累计成交量加权价格和累计成交量
- 把计算得到的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
相关产品推荐
相关产品推荐

