使用pandas的resample()计算成交量加权平均价遇错求助
嘿,我来帮你搞定这个VWAP计算的问题~
为什么resample().apply()会报错?
你遇到的AttributeError核心原因是:resample().apply()在默认行为下(尤其是旧版pandas)会逐列处理你的DataFrame——它会把每一列的分组结果单独以Series的形式传给lambda函数,而不是把整个分组的DataFrame传进去。
举个例子,你的代码里lambda函数拿到的x,其实是先传入price列的分组Series,再传入volume列的分组Series。这时候你写x.price,相当于给一个Series对象找price属性,自然就报错了。
而你用groupby()的方式能成功,是因为groupby().apply()默认会把整个分组的DataFrame传给lambda,所以x.price能正确访问到对应的列。
正确的resample()写法
方法1:让apply()接收整个分组的DataFrame
在较新的pandas版本中,直接这样写就能让apply()传递整个分组的DataFrame:
All.resample('1D').apply(lambda df: np.average(df['price'], weights=df['volume']))
如果你的pandas版本偏旧(比如0.20.x及更早),可以显式设置raw=False来强制传递DataFrame:
All.resample('1D').apply(lambda df: np.average(df['price'], weights=df['volume']), raw=False)
方法2:更高效的向量化写法(推荐)
其实不需要用apply,我们可以用向量化操作直接计算VWAP,性能比逐组循环的apply好很多,尤其是数据量大的时候:
# 计算每日的(price*volume)总和,除以每日volume总和 vwap = (All['price'] * All['volume']).resample('1D').sum() / All['volume'].resample('1D').sum()
这个逻辑和VWAP的定义完全一致,而且运行速度更快。
内容的提问来源于stack exchange,提问作者friend1




