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

非时间维度分桶:基于数量计算VWAP的Pandas/Numpy实现方法问询

简洁实现每50数量单位的VWAP计算

嘿,这个问题我太有共鸣了!之前用循环拆单个数量单位的方式处理,不仅代码臃肿,数据量大的时候慢得离谱。其实用 Pandas 结合 Numpy 的向量化操作就能高效解决,完全不用拆分成单个条目。下面是具体的实现思路和代码:

步骤1:构造测试数据

先把你给出的 DataFrame 构造出来,方便后续演示:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'price': [100, 102, 105, 99, 104, 103, 101],
    'quantity': [20, 31, 25, 40, 10, 20, 55]
})

步骤2:计算累积指标

先算出累积成交量和累积成交金额,这是后续分组计算的核心基础:

# 累积成交量
df['cum_qty'] = df['quantity'].cumsum()
# 累积成交金额(价格×数量的累积和)
df['cum_amt'] = (df['price'] * df['quantity']).cumsum()

步骤3:批量计算VWAP

核心思路是按每50单位的区间划分批次,通过搜索累积成交量的索引,快速定位每个批次覆盖的行,再计算该批次的总金额和总数量,最终得到VWAP:

# 生成所有批次的边界(0-50,50-100,...)
max_total_qty = df['cum_qty'].iloc[-1]
batch_bins = np.arange(0, max_total_qty + 50, 50)

vwap_list = []
for start, end in zip(batch_bins[:-1], batch_bins[1:]):
    # 定位批次覆盖的起始和结束行索引
    idx_start = df['cum_qty'].searchsorted(start, side='left')
    idx_end = df['cum_qty'].searchsorted(end, side='left') - 1
    
    total_qty = 0
    total_amt = 0
    
    # 处理批次内的完整行
    if idx_start <= idx_end:
        total_qty += df['quantity'].iloc[idx_start:idx_end+1].sum()
        total_amt += (df['price'] * df['quantity']).iloc[idx_start:idx_end+1].sum()
    
    # 处理起始行的部分成交量(当批次起始点不在累积量的节点上时)
    if idx_start > 0:
        prev_cum = df['cum_qty'].iloc[idx_start - 1]
        if start > prev_cum:
            partial_qty = start - prev_cum
            total_qty += partial_qty
            total_amt += df['price'].iloc[idx_start] * partial_qty
    
    # 处理结束行的部分成交量(当批次结束点不在累积量的节点上时)
    if idx_end < len(df) - 1:
        curr_cum = df['cum_qty'].iloc[idx_end]
        if end > curr_cum:
            partial_qty = end - curr_cum
            total_qty += partial_qty
            total_amt += df['price'].iloc[idx_end + 1] * partial_qty
    
    # 计算当前批次的VWAP(避免除以0的情况)
    if total_qty > 0:
        vwap = total_amt / total_qty
        vwap_list.append({
            '批次区间': f'{start}-{end}单位',
            'VWAP': round(vwap, 2),
            '实际成交量': total_qty
        })

# 转成DataFrame查看结果
vwap_result = pd.DataFrame(vwap_list)
print(vwap_result)

结果说明

运行后会得到每个50单位批次的VWAP值,哪怕某一行的成交量跨了两个批次(比如第2行的31单位,前10单位属于第一个批次,后21单位属于第二个批次),代码也能自动拆分计算,完全不需要循环处理单个数量单位。如果最后一批的成交量不足50单位,代码也会正常计算VWAP,你可以根据需求决定是否保留这一批。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:42:48