Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 高效VWAP计算_Python_Numpy_Pandas_Apply_Cumulative Sum - Fatal编程技术网

Python 高效VWAP计算

Python 高效VWAP计算,python,numpy,pandas,apply,cumulative-sum,Python,Numpy,Pandas,Apply,Cumulative Sum,我有下面的代码,使用它我可以通过三行代码计算成交量加权平均价格 import numpy as np import pandas as pd from pandas.io.data import DataReader import datetime as dt df = DataReader(['AAPL'], 'yahoo', dt.datetime(2013, 12, 30), dt.datetime(2014, 12, 30)) df['Cum_Vol'] = df['Volume'].

我有下面的代码,使用它我可以通过三行代码计算成交量加权平均价格

import numpy as np
import pandas as pd
from pandas.io.data import DataReader
import datetime as dt

df = DataReader(['AAPL'], 'yahoo', dt.datetime(2013, 12, 30), dt.datetime(2014, 12, 30))
df['Cum_Vol'] = df['Volume'].cumsum()
df['Cum_Vol_Price'] = (df['Volume'] * (df['High'] + df['Low'] + df['Close'] ) /3).cumsum()
df['VWAP'] = df['Cum_Vol_Price'] / df['Cum_Vol']
我试图找到一种方法来编写此代码,而不使用
cumsum()
作为练习。我正试图找到一种解决方案,一次通过
VWAP
列。我已经使用
.apply()
尝试了下面这一行。逻辑是存在的,但问题是我无法在第n行中存储值以在第(n+1)行中使用。在
pandas
中如何实现这一点-只需使用外部元组或字典临时存储累积值

df['Cum_Vol']= np.nan
df['Cum_Vol_Price'] = np.nan
# calculate running cumulatives by apply - assume df row index is 0 to N
df['Cum_Vol'] = df.apply(lambda x: df.iloc[x.name-1]['Cum_Vol'] + x['Volume'] if int(x.name)>0 else x['Volume'], axis=1)
上述问题是否有一次性解决方案

编辑:


我的主要动机是了解引擎盖下发生的事情。所以,它主要是为了锻炼而不是任何正当的理由。我相信大小为N的序列上的每个累积和都有时间复杂度N(?)。所以我想知道,与其运行两个单独的cumsum's,我们是否可以在一次过程中计算这两个值——沿着。非常乐意接受这个问题的答案,而不是工作代码。

进入一个关卡vs一行开始变得有点语义化。这有什么区别吗:你可以用一行熊猫、一行努比或者几行麻木来做

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()
时间:

%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

快速编辑:只是想感谢John的原创帖子:)

通过@jit-ing numpy的版本,您可以获得更快的结果:

@jit
def np_vwap():
    return np.cumsum(v*(h+l)/2) / np.cumsum(v)

这使我得到了
50.9µs/循环
,而不是使用上述vwap版本的
74.5µs/循环

使用apply将比使用way@EdChum,谢谢您有没有不使用cumsum的替代解决方案?目前没有,cumsum是一种矢量化方法,应用它是无法克服的。@JohnE,我的主要动机是了解引擎盖下发生的事情。所以,它主要是为了锻炼而不是任何正当的理由。我相信大小为N的系列上的每个
cumsum
都有时间复杂度N。因此我想知道我们是否可以一次计算两个独立的
cumsum
,而不是运行两个独立的
cumsum
。非常高兴接受这个答案-而不是工作代码。感谢改进!我只是自己计时,并没有得到很大的速度提升,但你的方式肯定更快。我认为随着时间的推移,numba在与numpy的结合方面已经变得更好了。