2014-04-06 24 views
1

熊貓的滾動和移動的概念掙扎。有很多好的建議,包括在這個論壇上,但我很失敗地把這些應用到我的場景中。Python熊貓時間系列w /分層索引和滾動/移位

現在我使用傳統的循環遍歷時間序列,但呃,花了8小時迭代超過150,000行,這是大約3天的所有代價數據。有兩個月的數據處理它可能不會完成後,我從休假回來,沒有提到電力切斷的風險之後,我不得不重新開始,這次沒有休假等待。

我有以下的15分鐘股價時間序列(分級指數DATETIME(時間戳)和股票,唯一的原列closePrice):

         closePrice 
    datetime    ticker 
    2014-02-04 09:15:00 AAPL  xxx 
          EQIX  xxx 
          FB  xxx 
          GOOG  xxx 
          MSFT  xxx 
    2014-02-04 09:30:00 AAPL  xxx 
          EQIX  xxx 
          FB  xxx 
          GOOG  xxx 
          MSFT  xxx 
    2014-02-04 09:45:00 AAPL  xxx 
          EQIX  xxx 
          FB  xxx 
          GOOG  xxx 
          MSFT  xxx 

我需要添加兩列:

  1. 12sma,12日均線。經過幾個小時的搜索,最好的建議是使用rolling_mean,所以我試了一下。但是,由於我的TS結構不起作用,即它能夠自頂向下運行,第一個MA根據前12行進行計算,而不管不同的股票價格。我該如何使平均值基於指數,即第一個日期時間然後行情,所以我得到MA說AAPL?目前它確實(AAPL + EQIX + FB + GOOG + MSFT + AAPL ...至第12行)/ 12
  2. 一旦我得到12sma列,我需要12ema列,12天指數MA。對於計算,每個行情的時間序列中的第一個值將從同一行復制12sma值。隨後,我需要來自同一行的closePrice和來自前一行的12ema,即過去15分鐘。我做了很長時間的研究,似乎解決方案將是滾動和移動的結合,但我無法弄清楚如何將它們放在一起。

任何幫助,我將不勝感激。

謝謝。

編輯:

感謝傑夫的技巧,交換和排序九級,我能夠得到與rolling_mean的12sma右後(),並用努力設法插入來自12sma在複印的第一12ema值相同的時間戳:

        close 12sma 12ema 
    sec_code datetime 
    AAPL  2014-02-05 11:45:00 113.0 NaN NaN 
      2014-02-05 12:00:00 113.2 NaN NaN 
      2014-02-05 13:15:00 112.9 NaN NaN 
      2014-02-05 13:30:00 113.2 NaN NaN 
      2014-02-05 13:45:00 113.0 NaN NaN 
      2014-02-05 14:00:00 113.1 NaN NaN 
      2014-02-05 14:15:00 113.3 NaN NaN 
      2014-02-05 14:30:00 113.3 NaN NaN 
      2014-02-05 14:45:00 113.3 NaN NaN 
      2014-02-05 15:00:00 113.2 NaN NaN 
      2014-02-05 15:15:00 113.2 NaN NaN 
      2014-02-05 15:30:00 113.3 113.16 113.16 
      2014-02-05 15:45:00 113.3 113.19 NaN 
      2014-02-05 16:00:00 113.2 113.19 NaN 
      2014-02-06 09:45:00 112.6 113.16 NaN 
      2014-02-06 10:00:00 113.5 113.19 NaN 
      2014-02-06 10:15:00 113.8 113.25 NaN 
      2014-02-06 10:30:00 113.5 113.29 NaN 
      2014-02-06 10:45:00 113.7 113.32 NaN 
      2014-02-06 11:00:00 113.5 113.34 Nan 

我瞭解大熊貓有pandas.stats.moments.ewma但我更喜歡使用一個公式,我從一本書,「此刻」和12ema從以前的行需要收盤價得到。

因此,我試圖從2月5日,15:45以後開始填充12ema列。我想申請()的功能,但移給了一個錯誤:

def f12ema(x): 
     K = 2/(12 + 1) 
     return x['price_nom'] * K + x['12ema'].shift(-1) * (1-K) 

    df1.apply(f12ema, axis=1) 

    AttributeError: ("'numpy.float64' object has no attribute 'shift'", u'occurred at index 2014-02-05 11:45:00') 

掠過我的心是rolling_appy(),但它是超出了我的知識,另一種可能性。

回答

1

創建日期範圍包容的時代,你想

In [47]: rng = date_range('20130102 09:30:00','20130105 16:00:00',freq='15T') 

In [48]: rng = rng.take(rng.indexer_between_time('09:30:00','16:00:00')) 

In [49]: rng 
Out[49]: 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2013-01-02 09:30:00, ..., 2013-01-05 16:00:00] 
Length: 108, Freq: None, Timezone: None 

創建一個類似你這樣的框架(2000年行情X日期)

In [50]: df = DataFrame(np.random.randn(len(rng)*2000,1),columns=['close'],index=MultiIndex.from_product([rng,range(2000)],names=['date','ticker'])) 

重新排序水平,使公司的股票X日期索引,SORT IT !!!!

In [51]: df = df.swaplevel('ticker','date').sortlevel() 

In [52]: df 
Out[52]: 
           close 
ticker date       
0  2013-01-02 09:30:00 0.840767 
     2013-01-02 09:45:00 1.808101 
     2013-01-02 10:00:00 -0.718354 
     2013-01-02 10:15:00 -0.484502 
     2013-01-02 10:30:00 0.563363 
     2013-01-02 10:45:00 0.553920 
     2013-01-02 11:00:00 1.266992 
     2013-01-02 11:15:00 -0.641117 
     2013-01-02 11:30:00 -0.574673 
     2013-01-02 11:45:00 0.861825 
     2013-01-02 12:00:00 -1.562111 
     2013-01-02 12:15:00 -0.072966 
     2013-01-02 12:30:00 0.673079 
     2013-01-02 12:45:00 0.766105 
     2013-01-02 13:00:00 0.086202 
     2013-01-02 13:15:00 0.949205 
     2013-01-02 13:30:00 -0.381194 
     2013-01-02 13:45:00 0.316813 
     2013-01-02 14:00:00 -0.620176 
     2013-01-02 14:15:00 -0.193126 
     2013-01-02 14:30:00 -1.552111 
     2013-01-02 14:45:00 1.724429 
     2013-01-02 15:00:00 -0.092393 
     2013-01-02 15:15:00 0.197763 
     2013-01-02 15:30:00 0.064541 
     2013-01-02 15:45:00 -1.574853 
     2013-01-02 16:00:00 -1.023979 
     2013-01-03 09:30:00 -0.079349 
     2013-01-03 09:45:00 -0.749285 
     2013-01-03 10:00:00 0.652721 
     2013-01-03 10:15:00 -0.818152 
     2013-01-03 10:30:00 0.674068 
     2013-01-03 10:45:00 2.302714 
     2013-01-03 11:00:00 0.614686 

           ... 

[216000 rows x 1 columns] 

Groupby the ticker。爲roll_mean和ewma的應用程序返回一個DataFrame。請注意,是用於控制這一點,e.g窗口許多選項,你可以把它不能環繞天等

In [53]: df.groupby(level='ticker')['close'].apply(lambda x: concat({ 'spma' : pd.rolling_mean(x,3), 'ema' : pd.ewma(x,3) }, axis=1)) 
Out[53]: 
           ema  spma 
ticker date         
0  2013-01-02 09:30:00 0.840767  NaN 
     2013-01-02 09:45:00 1.393529  NaN 
     2013-01-02 10:00:00 0.480282 0.643504 
     2013-01-02 10:15:00 0.127447 0.201748 
     2013-01-02 10:30:00 0.270334 -0.213164 
     2013-01-02 10:45:00 0.356580 0.210927 
     2013-01-02 11:00:00 0.619245 0.794758 
     2013-01-02 11:15:00 0.269100 0.393265 
     2013-01-02 11:30:00 0.041032 0.017067 
     2013-01-02 11:45:00 0.258476 -0.117988 
     2013-01-02 12:00:00 -0.216742 -0.424986 
     2013-01-02 12:15:00 -0.179622 -0.257750 
     2013-01-02 12:30:00 0.038741 -0.320666 
     2013-01-02 12:45:00 0.223881 0.455406 
     2013-01-02 13:00:00 0.188995 0.508462 
     2013-01-02 13:15:00 0.380972 0.600504 
     2013-01-02 13:30:00 0.188987 0.218071 
     2013-01-02 13:45:00 0.221125 0.294942 
     2013-01-02 14:00:00 0.009907 -0.228185 
     2013-01-02 14:15:00 -0.041013 -0.165496 
     2013-01-02 14:30:00 -0.419688 -0.788471 
     2013-01-02 14:45:00 0.117299 -0.006936 

     2013-01-04 10:00:00 -0.060415 0.341013 
     2013-01-04 10:15:00 0.074068 0.604611 
     2013-01-04 10:30:00 -0.108502 0.440256 
     2013-01-04 10:45:00 -0.514229 -0.636702 
           ...  ... 

[216000 rows x 2 columns] 

相當不錯PERF其本質上循環的行情。

In [54]: %timeit df.groupby(level='ticker')['close'].apply(lambda x: concat({ 'spma' : pd.rolling_mean(x,3), 'ema' : pd.ewma(x,3) }, axis=1)) 
1 loops, best of 3: 2.1 s per loop 
+0

非常感謝傑夫!花了我一段時間來研究你的答案。我不知道什麼交換索引級別可以實現,直到我閱讀你的答案和排序索引絕對加快了事情! –