2016-07-05 2 views
4

У меня есть dataframe с датой и значениями,скорость до панды dataframe итерации

Date  Price 
Jun 30 95.60 
Jun 29 94.40 
Jun 28 93.59 
Jun 27 92.04 
Jun 24 93.40 
Jun 23 96.10 
Jun 22 95.55 
Jun 21 95.91 
Jun 20 95.10 
Jun 17 95.33 
Jun 16 97.55 
Jun 15 97.14 
Jun 14 97.46 
Jun 13 97.34 
Jun 10 98.83 
Jun 9  99.65 
Jun 8  98.94 
Jun 7  99.03 
Jun 6  98.63 
Jun 3  97.92 
Jun 2  97.72 

Там есть функция, которая перебирать dateframe,

indic_up = [False, False,False, False] 
i = 4 
while i+4 <= df.index[-1]: 
    if (df.get_value(i, 'value') > df.get_value(i-1, 'value')) or 
     (df.get_value(i, 'value') > df.get_value(i-2, 'value')) or 
     (df.get_value(i, 'value') > df.get_value(i-3, 'value')) or 
     (df.get_value(i, 'value') > df.get_value(i-4, 'value')):indic_up.append(True) 
    else:indic_up.append(False) 
    i = i+1 

Логика этой функции, если value сегодня больше, чем вчера, позавчера или раньше, то это true или false. Эти функции, как представляется, очень медленно для меня, так как я могу переписать эту функцию, как эти

for index, row in df.iterrows(): 
row['a'], index 

или

for idx in df.index: 
df.ix[idx, 'a'], idx 

или может я достичь более быстрой путем преобразования dataframe в Numpy массив?

ответ

2

Приглашаем Scipy тоже!

Идея: Сравните текущий элемент с предыдущими значениями 4, вычисляя минимум в этом интервале и сравнивая с текущим. Если это соответствует, мы в основном провалили все сравнения и, таким образом, выберем False. Итак, кодовое, просто сравните текущий элемент с минимумом в этом интервале. Здесь scipy приходит с minimum_filter.

Реализация:

from scipy.ndimage.filters import minimum_filter 

# Extract values from relevant column into a NumPy array for further procesing 
A = df['value'].values 

# Look for no match with interval-ed min & look for NOT matching for True as o/p 
indic_up_out = A != minimum_filter(A,footprint=np.ones((5,)),origin=2) 

# Set first four as False because those would be invalid with a 5 elem runway 
indic_up_out[:4] = 0 
1

Вы можете фактически раз. Вот мой эксперимент. Он показывает, что цикл над списком намного быстрее, чем ваш метод. Ответ от @Divakar на самом деле очень хороший.

import pandas as pd 
import timeit 
import numpy as np 

df = pd.DataFrame({'Date':['Jun 30', 'Jun 29', 'Jun 28', 'Jun 27', 'Jun 24', 'Jun 23', 'Jun 22', 'Jun 21', 'Jun 20', 'Jun 17', 
         'Jun 16','Jun 15', 'Jun 14', 'Jun 13', 'Jun 10', 'Jun 9', 'Jun 8', 'Jun 7', 'Jun 6', 'Jun 3', 'Jun 2'], 
      'value': ['95.60', '94.40', '93.59', '92.04', '93.40', '96.10', '95.55', '95.91', '95.10', '95.33', '97.55', 
         '97.14', '97.46', '97.34', '98.83', '99.65', '98.94', '99.03', '98.63', '97.92', '97.72']}) 


def by_df_get_value(): 
    indic_up = [False, False,False, False] 
    i = 4 
    while i+4 <= df.index[-1]: 
     if (df.get_value(i, 'value') > df.get_value(i-1, 'value')) or \ 
     (df.get_value(i, 'value') > df.get_value(i-2, 'value')) or \ 
     (df.get_value(i, 'value') > df.get_value(i-3, 'value')) or \ 
     (df.get_value(i, 'value') > df.get_value(i-4, 'value')): 

     indic_up.append(True) 
    else: 
     indic_up.append(False) 
    i = i+1 


def by_list(): 
    indic_up = [False, False,False, False] 
    values = df['value'].tolist() 
    for i, v in enumerate(values): 
     if i < 4: 
      continue 
     if (v > values[i-1]) or \ 
      (v > values[i-2]) or \ 
      (v > values[i-3]) or \ 
      (v > values[i-4]): 
      indic_up.append(True) 
     else: 
      indic_up.append(False) 

total_time = [] 
for i in range(10): 
    t = timeit.Timer('by_df_get_value()','from __main__ import by_df_get_value').timeit(number=1) 
    total_time.append(t) 
print('by_df_get_value(): ', '{:.20f}'.format(np.mean(total_time))) 


total_time = [] 
for i in range(10): 
    t = timeit.Timer('by_list()','from __main__ import by_list').timeit(number=1) 
    total_time.append(t) 
print('by_list', '{:.20f}'.format(np.mean(total_time))) 

Вот выход на моей машине:

by_df_get_value(): 0.00015220100467558951 
by_list(): 0.00002649170055519790 
Смежные вопросы