2016-02-12 71 views
0

我有一個類似的問題在這裏的一個(dataframe by index and by integer)大熊貓由布爾值數據框,通過索引,以及整數

我要的是一個布爾值索引來獲取數據框的部分(容易),並期待在一個很少有數值落後,比如在前一個指數中可能還有其他數值。不幸的是,在get_loc的鏈接問題中的建議答案使我的代碼片段窒息(在下面的片段中輸入錯誤),然後才能獲得實際的整數位置。

以同樣的例子如在其他問題的答案,這裏是我的嘗試:

df = pd.DataFrame(index=pd.date_range(start=dt.datetime(2015,1,1), end=dt.datetime(2015,2,1)), data={'a':np.arange(32)}) 
df.index.get_loc(df.index[df['a'] == 1]) 
*** TypeError: Cannot convert input to TimeStamp 

以前的答案使用字符串get_loc,我只是想傳遞一個簡單的索引值(這裏一個DateTime)

+0

你df.index.get_loc後'(DF [DF [ '一'] == 1]的.index [0 ])'假設有一個匹配項 – EdChum

+0

「向後看幾個值」是什麼意思? 'df.loc [df ['a'] == 1]'是否足夠? – unutbu

+0

@EdChum你的建議適用於一次打擊,但如果很多值匹配,那麼這個比例就不會縮放,我想要所有的位置而不僅僅是第一個位置。 –

回答

1

使用切片

import numpy as np 
import pandas as pd 
import datetime as DT 
index = pd.date_range(start=DT.datetime(2015,1,1), end=DT.datetime(2015,2,1)) 
df = pd.DataFrame({'a':np.arange(len(index))}, index=index) 

mask = df['a'] == 1 
idx = np.flatnonzero(mask)[0] 
lookback = 3 
print(df.iloc[max(idx-lookback, 0):idx+1]) 

產量

   a 
2015-01-08 7 
2015-01-09 8 
2015-01-10 9 
2015-01-11 10 

注意,如果idx-lookback是否定的,則該指數指的是元件附近的df尾部,就像Python列表:

In [163]: df.iloc[-3:2] 
Out[163]: 
Empty DataFrame 
Columns: [a] 
Index: [] 

In [164]: df.iloc[0:2] 
Out[164]: 
      a 
2015-01-01 0 
2015-01-02 1 

因此,抓住相對的df的頭元件,使用max(idx-lookback, 0)


使用布爾面具

你知道,如果你有一個布爾數組或布爾系列如

mask = df['a'] == 10 

你可以用

選擇對應的行
df.loc[mask] 

如果你想選擇以前或su一個固定的量,你可以使用mask.shift到掩模移動轉移cceeding行:

lookback = 3 
for i in range(1, lookback): 
    mask |= mask.shift(-i) 

df.loc[mask.shift(-lookback).fillna(False)] 

如果您想選擇lookback前述行,那麼你可以通過它的變化unioning展開該面具

,或者等價地,使用cumsum

mask = (mask.shift(-lookback) - mask.shift(1)).cumsum().fillna(False).astype(bool) 

for-loop是清晰的,但cumsum EXP熱情更快,特別是如果lookback大。


例如,

import numpy as np 
import pandas as pd 
import datetime as DT 
df = pd.DataFrame(
    index=pd.date_range(start=DT.datetime(2015,1,1), end=DT.datetime(2015,2,1)), 
    data={'a':np.arange(32)}) 

mask = df['a'] == 10 
lookback = 3 
for i in range(1, lookback): 
    mask |= mask.shift(-i) 

# alternatively, 
# mask = (mask.shift(-lookback) - mask.shift(1)).cumsum().fillna(False).astype(bool) 

print(df.loc[mask]) 

產生

   a 
2015-01-08 7 
2015-01-09 8 
2015-01-10 9 
2015-01-11 10 
+0

嗨unutbu,如果我想要什麼從'-lookback'上的行開始將所有行開始到當前匹配的行?這就是爲什麼我的第一種方法是尋找一種方式來推斷當前匹配的行號(例如'm'),以便我可以像這樣'df.ix [m-lookback:m]'或'df.iloc [ m-lookback:m]'(我想第二種形式更快一些,因爲它專門用於整數索引)。我要玩你的布爾指數轉變方法。 –

+0

感謝'np.flatnonzero' –