2015-03-27 4 views
5

मेरे पास निम्न कोड है, जिसका उपयोग मैं पांडस कोड की तीन पंक्तियों द्वारा वॉल्यूम-भारित औसत मूल्य की गणना कर सकता हूं।पांडस कुशल वीडब्ल्यूएपी गणना

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() का उपयोग करके नीचे दी गई पंक्ति का प्रयास किया है। तर्क वहां है, लेकिन मुद्दा यह है कि मैं पंक्ति (एन + 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) 

क्या उपर्युक्त समस्या का एक-पास समाधान है?

संपादित करें:

मेरा मुख्य प्रेरणा को समझने के लिए क्या हुड के नीचे हो रहा है। इसलिए, यह मुख्य रूप से किसी वैध कारण से व्यायाम के लिए है। मेरा मानना ​​है कि आकार एन की श्रृंखला पर प्रत्येक cumsum समय जटिलता एन (?) है। तो मैं सोच रहा था, दो अलग-अलग cumsum चलाने के बजाय, हम this की लाइनों के साथ-साथ दोनों पास की गणना कर सकते हैं। काम करने के बजाए इसका जवाब स्वीकार करने में बहुत खुशी हुई।

+0

आवेदन का उपयोग – EdChum

+0

@EdChum के तरीके से आपकी पहली विधि से काफी धीमा होगा, धन्यवाद, क्या आपके पास 'cumsum' का उपयोग किये बिना वैकल्पिक समाधान है? – Rhubarb

+0

इस समय नहीं, cumsum एक वेक्टरिज्ड विधि लागू है इसे हरा नहीं होगा। – EdChum

उत्तर

8

एक पास बनाम एक पंक्ति में होना थोड़ा सा सैद्धांतिक प्राप्त करना शुरू होता है। इसके बारे में एक भेद के लिए: आप इसे पांडा की 1 पंक्ति, numpy की 1 पंक्ति, या 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() 

समय:

%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 
3

त्वरित संपादन:

: बस मूल पोस्ट :)

आप कर सकते हैं पाने @ JIT-इंग numpy के संस्करण से भी तेजी से परिणाम के लिए जॉन को धन्यवाद देना चाहता था

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

यह मुझे 50.9 µs per loop के रूप में मिला उपरोक्त vwap संस्करण का उपयोग कर 74.5 µs per loop पर pposed।

+1

सुधार के लिए धन्यवाद! मैंने बस इसे खुद का समय दिया और काफी तेज गति नहीं मिली, लेकिन आपका रास्ता निश्चित रूप से तेज़ है। मुझे लगता है कि numba समय के साथ numpy के साथ संयोजन में बेहतर हो गया है। – JohnE