2016-07-05 2 views
4
dateframe을 반복하는 기능이있다

속도까지 판다는 반복

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 

내가 날짜와 값이 dataframe이

,

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 

이 함수의 논리입니다 dataframe 오늘의 value 경우 어제보다 크거나 어제 전이거나 그 전에는 true 또는 false입니다. 이 기능은 나에게 매우 느린 것 같다, 그래서 내가 어떻게이

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

또는

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

같은이 기능을 다시 작성할 수 있습니다 또는 내가 NumPy와 배열에 dataframe를 변환하여 더 빠르게 달성 할 수있다?

답변

2

Scipy을 초대합니다.

아이디어 : 현재 요소와 이전 4 값을 비교하여 해당 간격의 최소값을 계산하고 현재 값과 비교합니다. 일치하는 경우 기본적으로 모든 비교가 실패하여 False을 선택합니다. 그래서, 동시 적으로, 그냥 그 간격에서 현재 요소를 최소와 비교하십시오. 여기서 scipyminimum_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의 대답은 사실 아주 좋습니다.

by_df_get_value(): 0.00015220100467558951 
by_list(): 0.00002649170055519790 
: 여기

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))) 

내 컴퓨터에서 출력