Pandas Efficient VWAP Calculation
Quick Edit: Just wanted to thank John for the original post :)
You can get even faster results by @jit-ing numpy's version:
@jit
def np_vwap():
return np.cumsum(v*(h+l)/2) / np.cumsum(v)
This got me 50.9 µs per loop
as opposed to 74.5 µs per loop
using the vwap version above.
Getting into one pass vs one line starts to get a little semantical. How about this for a distinction: you can do it with 1 line of pandas, 1 line of numpy, or several lines of numba.
from numba import jit
df=pd.DataFrame( np.random.randn(10000,3), columns=['v','h','l'] )
df['vwap_pandas'] = (df.v*(df.h+df.l)/2).cumsum() / df.v.cumsum()
@jit
def vwap():
tmp1 = np.zeros_like(v)
tmp2 = np.zeros_like(v)
for i in range(0,len(v)):
tmp1[i] = tmp1[i-1] + v[i] * ( h[i] + l[i] ) / 2.
tmp2[i] = tmp2[i-1] + v[i]
return tmp1 / tmp2
v = df.v.values
h = df.h.values
l = df.l.values
df['vwap_numpy'] = np.cumsum(v*(h+l)/2) / np.cumsum(v)
df['vwap_numba'] = vwap()
Timings:
%timeit (df.v*(df.h+df.l)/2).cumsum() / df.v.cumsum() # pandas
1000 loops, best of 3: 829 µs per loop
%timeit np.cumsum(v*(h+l)/2) / np.cumsum(v) # numpy
10000 loops, best of 3: 165 µs per loop
%timeit vwap() # numba
10000 loops, best of 3: 87.4 µs per loop