Эффективное вычисление VWAP Pandas

У меня есть код ниже, с помощью которого я могу рассчитать средневзвешенную по объему цену тремя строками кода Pandas.

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() строку, используя .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) 

Существует ли однопроходное решение этой проблемы?

РЕДАКТИРОВАТЬ:

Моя главная мотивация – понять, что происходит под капотом. Таким образом, это в основном для физических упражнений, чем любая действительная причина. Я считаю, что каждая cumsum на серии размера N имеет временную сложность N (?). Поэтому мне было интересно, вместо того, чтобы запускать две отдельные cumsum, мы можем рассчитать оба за один проход – по строкам этого . Очень рад принять ответ на этот вопрос, а не рабочий код.

2 Solutions collect form web for “Эффективное вычисление VWAP Pandas”

Переход в один проход против одной линии начинает немного семантически. Как насчет этого для различия: вы можете сделать это с помощью 1 строки панд, 1 строки numpy или нескольких строк 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 

Quick Edit: просто хотел поблагодарить Джона за оригинальное сообщение 🙂

Вы можете получить даже после результатов по версии @ jit-ing numpy:

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

Это обеспечило мне 50.9 µs per loop а не 74.5 µs per loop используя версию vwap выше.

  • python pandas стандартизовать столбец для регрессии
  • pandas находит строки среди рядов и возвращают ключевые слова
  • ускорить работу python
  • Понимание вывода из рекурсивной функции
  • Pandas: как передать имя столбца функции, которая затем может использоваться в 'apply'?
  • Прочитайте файл с разделяемой вкладкой с первым столбцом в качестве ключа, а остальные как значения
  • pandas находят ряды среди рядов
  • Замена Pandas / медленность словаря
  • Python - лучший язык программирования в мире.