2017-04-18 40 views
1

假設我有一個數據幀獲取數據幀前面和後面的指數值應他們的存在

df = pd.DataFrame(dict(vals=np.random.randint(0, 10, 10)), 
        index=pd.date_range('20170401', '20170410')) 

>>> df 
       vals 
2017-04-01  9 
2017-04-02  8 
2017-04-03  4 
2017-04-04  5 
2017-04-05  9 
2017-04-06  9 
2017-04-07  5 
2017-04-08  3 
2017-04-09  3 
2017-04-10  1 

和我知道是我的索引,但不知道的位置的特定日期,例如

cur_dt = df.index[np.random.randint(0, df.index.size)] 

>>> cur_dt 
Timestamp('2017-04-05 00:00:00', freq='D') 

鑑於cur_dt,我想確定我的索引中的前一個值和下一個值是什麼。 cur_dt應該是我的索引中的第一個(最後一個)值,那麼上一個(下一個)元素本身應該是cur_dt

回顧一下,我的問題是,在我的索引中查找上一個和下一個值(或者我的當前值,如果它是一個端點)給出我當前值的最簡單方法是什麼?


我目前的做法似乎頗爲迂迴,這是我提問的動機。

cur_iloc = df.index.get_loc(cur_dt) 
prev = cur_dt if cur_iloc == 0 else df.index[cur_iloc-1] 
next = cur_dt if cur_iloc == df.index.size-1 else df.index[cur_iloc+1] 

>>> prev 
Timestamp('2017-04-04 00:00:00', freq='D') 
>>> next 
Timestamp('2017-04-06 00:00:00', freq='D') 

如果沒有更直接的方式,那麼我的道歉。我想象一下,只要將我的指數從我目前的價值中「轉移」一次,然後一次回落(對終點有一些很好的治療),但我不確定這是否可行。

回答

3

假設指數進行排序,嘗試使用numpy.searchsorted

來源的數據集:

In [185]: df 
Out[185]: 
      vals 
2017-04-01  5 
2017-04-02  3 
2017-04-03  9 
2017-04-04  8 
2017-04-05  1 
2017-04-06  0 
2017-04-07  4 
2017-04-08  5 
2017-04-09  1 
2017-04-10  8 

In [186]: cur_dt 
Out[186]: Timestamp('2017-04-02 00:00:00', freq='D') 

解決方案:

In [187]: idx = np.searchsorted(df.index, cur_dt) 

In [188]: df.index[max(0, idx-1)] 
Out[188]: Timestamp('2017-04-01 00:00:00', freq='D') 

In [189]: df.index[min(idx+1, len(df)-1)] 
Out[189]: Timestamp('2017-04-03 00:00:00', freq='D') 
+0

啊這是一個改進,絕對更清晰和更短。謝謝Max!一個問題,也許是:有什麼特別的原因,我應該更喜歡'np.searchsorted'到'df.index.get_loc'? –

+0

@EricHansen,'df.index.get_loc' - 與'np.searchsorted'相比可能會更快(或不會)。我認爲最好的方法是根據您的數據對其進行測試;-) – MaxU

+1

這很公平。還有一個骨頭要和你一起挑選;)我認爲它應該是'len(df)-1',否? –

1

重置您的索引,然後使用您的布爾邏輯來確定您的的位置0像這樣:

df = df.reset_index() 
cur_dt_index = df.index[np.random.randint(0, df['index'].size)] 
previous = max(cur_dt_index-1, 0) 
next = min(cur_dt_index + 1, df.shape[0]) 
相關問題