2015-04-07 57 views
2

在熊貓中一遍又一遍,我發現我必須劃分一段特定的時間。例如,對於時間序列中的每一天,請在每個中午12點將每個值除以值。Python熊貓時間系列比較具體時間

我覺得這應該是一個相當簡單的操作,但我沒有找到簡單的解決方案。

例如,我想在時間序列上每天執行一個功能:

x = df.groupby(df.index.date).apply(func) 

每一天,做:

def func(df): 
    st = df.between_time('10:00','10:00')['y-value'] 
    end = df.between_time('14:45','14:45')['y-value'] 
    return (st/end) 

首先,有沒有辦法說, df.at_time('10:00' )?在這裏寫betweenbetweenbetween()看​​起來很迂迴,但它起作用。我也嘗試df.index.time,但我不確定如何說,== datetime.time(10,0),因爲它返回一個布爾數組,而不僅僅是上午10點的值。

該函數不起作用,因爲我認爲這是一個索引問題,它會在每個值處吐出N/A併爲每一天吐出兩個值(即在10:00和14:45分別爲1 ), 不是一個。 如果它們是相同的時間,這會起作用,但如果它們是不同的時間則不起作用。我被引導認爲算術運算不能在不同的日期時間乾淨地工作。

我也試過:

def func(df): 
    st = df.reset_index().between_time('10:00','10:00')['mid'].values[0] 
    end = df.reset_index().between_time('14:45','14:45')['mid'].values[0] 
    return (st/end) 

我得到一個索引錯誤說我需要返回DateTimeIndex。我認爲我不能只是將值分開,它會將該值返回到相應的日期,而是需要返回某種(索引,值)熊貓物體。

任何想法?這是一種常見的操作?

這裏是我的數據集的樣子(使用pd.read_clipboard()讀取):

     bid ask  mid 
2000-01-01 12:00:00 288.0 289.5 288.75 
2000-01-01 13:30:00 287.8 288.6 288.20000000000005 
2000-01-01 14:00:00 287.75 289.25 288.5 
2000-01-03 09:30:00 288.5 289.5 289.0 
2000-01-03 10:15:00 288.5 289.5 289.0 
2000-01-03 10:30:00 289.0 290.0 289.5 
2000-01-03 10:45:00 288.75 289.75 289.25 
2000-01-03 11:45:00 288.75 289.75 289.25 
2000-01-03 13:00:00 288.5 289.5 289.0 
2000-01-03 13:15:00 288.5 289.5 289.0 
2000-01-03 13:30:00 288.5 289.5 289.0 
2000-01-04 09:00:00 281.5 282.25 281.875 
2000-01-04 09:15:00 281.0 281.5 281.25 
2000-01-04 09:30:00 281.25 281.75 281.5 
2000-01-04 09:45:00 281.1 281.85 281.475 
2000-01-04 10:00:00 281.7 282.2 281.95 
2000-01-04 10:30:00 282.0 282.75 282.375 
2000-01-04 10:45:00 282.2 282.95 282.575 
2000-01-04 11:15:00 282.3 282.8 282.55 
2000-01-04 11:30:00 281.45 282.2 281.825 

UPDATE:臨時的解決辦法,但我要找的東西清潔劑(它不存在,這是可能的)

st_time, end_time = '8:00', '14:45' 
st, end = df.at_time(st_time), df.at_time(end_time) 
AM = st.merge(end, on='date', how='left').dropna() 
AM = AM.set_index(pd.DatetimeIndex(AM['date'])) 
AM['AM return'] = (AM[end_time]/AM[st_time]) - 1 
AM = AM.rename(columns={'price_x': st_time+' price', 'price_y': end_time+' price'}) 
+0

顯示您期待輸出的示例 – Jeff

+0

您每天只有第一天的12點沒有價值。 –

+0

嘗試返回'(st/end.values)' – HYRY

回答

0

這裏有一種方法做什麼,我想你想要的。

將原始幀重新索引爲包含範圍中的所有日期。這確保'12:00'將存在;向前填充以傳播值。

In [66]: y = df.reindex(pd.date_range(df.index.min().date(),(df.index.max() + pd.offsets.Day()).date(), closed='left', freq='15T'), method='ffill') 

In [67]: y.info() 
<class 'pandas.core.frame.DataFrame'> 
DatetimeIndex: 384 entries, 2000-01-01 00:00:00 to 2000-01-04 23:45:00 
Freq: 15T 
Data columns (total 3 columns): 
bid 336 non-null float64 
ask 336 non-null float64 
mid 336 non-null float64 
dtypes: float64(3) 
memory usage: 12.0 KB 

將新系列除以'12:00'的值。請注意,您必須在此刪除索引(使用.values)以正確播放它。重新索引到您的原始框架。

In [68]: (y/y.groupby(y.index.date).transform(lambda x: x.at_time('12:00').values)).reindex(df.index) 
Out[68]: 
          bid  ask  mid 
2000-01-01 12:00:00 1.000000 1.000000 1.000000 
2000-01-01 13:30:00 0.999306 0.996891 0.998095 
2000-01-01 14:00:00 0.999132 0.999136 0.999134 
2000-01-03 09:30:00 0.999134 0.999137 0.999136 
2000-01-03 10:15:00 0.999134 0.999137 0.999136 
2000-01-03 10:30:00 1.000866 1.000863 1.000864 
2000-01-03 10:45:00 1.000000 1.000000 1.000000 
2000-01-03 11:45:00 1.000000 1.000000 1.000000 
2000-01-03 13:00:00 0.999134 0.999137 0.999136 
2000-01-03 13:15:00 0.999134 0.999137 0.999136 
2000-01-03 13:30:00 0.999134 0.999137 0.999136 
2000-01-04 09:00:00 1.000178 1.000177 1.000177 
2000-01-04 09:15:00 0.998401 0.997519 0.997960 
2000-01-04 09:30:00 0.999289 0.998405 0.998847 
2000-01-04 09:45:00 0.998756 0.998760 0.998758 
2000-01-04 10:00:00 1.000888 1.000000 1.000444 
2000-01-04 10:30:00 1.001954 1.001949 1.001952 
2000-01-04 10:45:00 1.002665 1.002658 1.002661 
2000-01-04 11:15:00 1.003020 1.002126 1.002573 
2000-01-04 11:30:00 1.000000 1.000000 1.000000 

這應該對您的輸入範圍和向量化穩健。然而,我認爲可以提高語法/易用性。

+0

我會測試這個 –