2017-02-20 136 views
4

我在['符號']列中確定以下時間序列中的正面和負面時間段。我怎樣才能得到1和-1的每個持續時間,然後用1和-1來計算週期數?如何查找熊貓時間序列的事件持續時間

因此,如果我在['sign']列中連續五個'1',然後連續三個'-1',然後是兩個'1',則答案是持續時間:5天,3天和2天。然後數數。 '1':2和 '-1':1.

import pandas_datareader.data as web 
import datetime as dt 
import numpy as np 
import pandas as pd 

end = dt.datetime(2016, 12, 31) 
start = dt.date(end.year-15, end.month, end.day) 

aapl = web.DataReader('AAPL', 'yahoo', start, end)['Adj Close'] 
aapl = pd.DataFrame(aapl) 
aapl['ema'] = aapl.ewm(200).mean() 
aapl['diff'] = (aapl['Adj Close']/aapl['ema']) - 1 
aapl['sign'] = np.sign(aapl['diff']) 

UPDATE: 我意識到,需要週期其中sign = '1',並簽署=單獨的計數 '-1',當涉及持續時間。這是對'1'和'-1'時期的描述性統計。

大熊貓版本:0.19.2

+0

對於UPDATE部分,你可以添加一個樣本和預期的o/p? – Divakar

+0

In [1]:duration_up_count(a) Out [2]:(array([5,2]))使用你的數組,等價於down。然後跳過累計計數。 – cJc

回答

3

您可以使用diff()和隨後cumsum()得到的差異在系列中,並相應地groupby。

aapl.groupby((aapl.sign.diff() != 0).cumsum()).size() 

至於讓每個星座羣的數量,有可能是一個更聰明的方式來做到這一點,但刪除重複後,你可以重新使用相同的diff結果索引原始sign系列。

aapl.sign.iloc[(aapl.sign.diff() != 0).cumsum().drop_duplicates().index] 
       .value_counts().to_dict() 

把這個很好的功能可能看起來像

def durs(df): 
    diffs = (df.sign.diff() != 0).cumsum() 
    cnts = df.sign.iloc[diffs.drop_duplicates().index].value_counts().to_dict() 
    days = df.groupby(diffs).size() 
    return days, cnts 

演示

>>> df 
    sign 
0  1 
1  1 
2  1 
3  1 
4  1 
5 -1 
6 -1 
7 -1 
8  1 
9  1 

>>> days, cnts = durs(df) 

>>> days 
sign 
1 5 
2 3 
3 2 
dtype: int64 

>>> cnts 
{-1: 1, 1: 2} 

更新

對於在計數的1期和隨後得到的[5, 2]輸出的評論讓您的要求,您可以使用這樣的事情,得到的1的指數,然後通過consecutives分組。

>>> data = np.where(df.sign == 1)[0] 

>>> np.diff(np.r_[0, np.where(np.diff(data) != 1)[0]+1, data.size]) 
array([5, 2]) 

你要知道,我不是一個NumPy的專家,所以沒有關於此的性能保證。

+0

當我從我的問題的數據框上運行你的函數時,我得到以下代碼的錯誤信息:cnts = df.sign.iloc [diffs.drop_duplicates()。索引] .value_counts()。to_dict()錯誤消息:TypeError:無效類型促銷 – cJc

+0

@cJc您正在使用哪種版本的熊貓? – miradulo

+0

我意識到,在持續時間方面,需要單獨計算sign ='1'和sign ='-1'的期間。這是對'1'和'-1'時期的描述性統計。 – cJc

1

下面是一個數組的一種方法 -

def duration_count(a): 
    idx = np.r_[[0],np.flatnonzero(a[1:] != a[:-1])+1,a.size] 
    duration = np.diff(idx) 
    count = {a[0]:(duration.size+1)//2, -a[0]:duration.size//2} 
    return duration, count 

樣品試驗 -

In [43]: a = np.array([1,1,1,1,1,-1,-1,-1,1,1]) 

In [44]: duration_count(a) 
Out[44]: (array([5, 3, 2]), {-1: 1, 1: 2}) 

In [45]: a = np.array([-1,-1,1,1,1,1,1,-1,-1,-1,1,1,-1,-1,-1,-1]) 

In [46]: duration_count(a) 
Out[46]: (array([2, 5, 3, 2, 4]), {-1: 3, 1: 2}) 
+0

請參閱更新後的問題:我意識到,在持續時間方面,需要單獨計數sign ='1'和sign ='-1'的期間。這是對'1'和'-1'時期的描述性統計。 – cJc