2015-03-25 232 views
0

十萬,我有以下數據框:比較快的方式來比較值

Price, Volume 
100, 45656 
101, 67563 
103, 755 
... 
... 
6543, 67567 
6544, 7654 

在價格欄的每一項都是獨特的,有幾千行。我們的目標是確定一個滾動行數範圍內的低批量價格。換句話說,我沒有試圖確定整個數據框中的最低音量。我在一個滾動的「窗口」上標識了很多低音量的行。

可以說我將滾動窗口設置爲50.我所做的是將當前音量值與上面的50個音量值以及它下面的50個音量值進行比較。如果當前音量值在該範圍內最低,我將相應的價格保存到單獨的列表中。然後我再向下移動一行,並再次比較以查看當前音量值是否小於50以上和以下。下面

我的代碼工作正確地完成這項任務:

rolling_window = 50 
total_rows = len(df.index) 
current_row = rolling_window 
smallest_values = [] 

while current_row < total_rows - rolling_window: 
    is_smallest = True 
    for comparison_row in range(rolling_window): 
     if vp.iloc[current_row]['Volume'] > vp.iloc[current_row - comparison_row]['Volume'] or \ 
      vp.iloc[current_row]['Volume'] > vp.iloc[current_row + comparison_row]['Volume']: 
      is_smallest = False 
      break 
    if is_smallest and vp.iloc[current_row]['Price'] not in smallest_values: 
     smallest_values.append(vp.iloc[current_row]['Price']) 
    current_row += 1 

print(smallest_prices) 

我的問題是,它與大dataframes(幾千項)時也非常緩慢。我相信必須有一個更好的方式來完成即時通訊嘗試做的更有效。我害怕即時通訊算法使得算法做了比必要的更多的工作,但是我一直沒有想到用另一種方式來做到這一點。

如果有人可以提出更快/更有效的方法,我將不勝感激。

+0

你應該如何處理關係(同分卷價格不同窗口中)? – Alexander 2015-03-25 08:15:29

+0

@Alexander它應該理想地保存所有的關係。即:如果窗口內有幾個價格都相同,應該保存所有價格 – darkpool 2015-03-25 08:20:32

回答

1

步驟1:實施一個101分鐘(從當前點起50上降50下)的滾動分鐘。

步驟2:中心通過50.

步驟3他們下移這些最小值:比較體積與移位最小值。如果它們匹配,那麼這應該是窗口內價格最低的價格。

第4步:過濾匹配。

第5步:享受額外的空閒時間!

import pandas as pd 
import bumpy as np 

df = pd.DataFrame({'price': range(1000), 
        'volume': np.random.random_integers(0, 500000, 1000)}) 
df['min_volume'] = pd.rolling_min(df.volume, 101) 
df['min_shift'] = df['min_volume'].shift(-50) 
df['match'] = df.volume == df.min_shift 
>>> df[df.match] 
Out[39]: 
    price volume min min_shift match 
181 181 4317 4317  4317 True 
245 245 4478 4317  4478 True 
358 358 1118 1118  1118 True 
427 427 7251 1118  7251 True 
504 504 10680 7251  10680 True 
631 631 1096 1096  1096 True 
699 699  277 277  277 True 
770 770 2037 277  2037 True 
828 828  310 310  310 True 
931 931  516 516  516 True 

得到公正的價格:

df[df.match].price 
+0

它還可以保存與窗口內最小值相關的所有價格。 – Alexander 2015-03-25 08:38:04

+0

btw,我的DataFrame有'min',但代碼片段有'min_volume'。在最初運行該變量後,我將該變量重命名以避免與最小DataFrame方法發生任何名稱衝突。 – Alexander 2015-03-25 08:48:48

+0

優秀@Alexander。非常感謝你。這是一些我永遠無法做到的忍者代碼。 – darkpool 2015-03-25 08:59:42

2

跳過49(從最低)而不是一個更合理嗎?因爲接下來的49個值不能低於剛剛找到的值,如果它是最低的。

此外,在另一方面,您可能會嘗試使用有序地圖,因爲您說價格都是唯一的。然後,您可以只看地圖的一端(取決於它的排序方式)以取消最小的鍵/值對。當然,我假設該地圖的實現已經完成,但是如果它位於標準庫中,那很可能是。

通過這種方式,您可以將列表中的100個值一次輸入到地圖中,並且擁有全盛時期的值。

+0

謝謝羅恩。是的,你是正確的我只是檢查了這一點,它減少了約三分之一的算法的運行時間。非常感謝,我會更新原文。但它仍然非常緩慢。處理幾千個條目需要幾分鐘時間。 – darkpool 2015-03-25 08:16:22

+0

羅恩,唯一的問題就是亞歷山大提到的關係(價格等量)。通過這樣做,該算法可以保存第一個最小音量,但是然後跳過可能會丟失任何不需要的關係。 – darkpool 2015-03-25 08:23:18

+0

我能想到的另一個優化是跳到100(並且只存儲每組100的最小值)。這應該減少另一個因子2的比較次數。使用該方法,您還可以存儲關係。無論如何,50以前和之後都是一組100。只需找到第一組中的最後一個最小值並跳轉(98?),並比較以前的99個值。無論哪種方式,你可以存儲關係,因爲你知道最低限度,所以你可以跳過最後的領帶。 – 2015-03-25 08:24:21