2016-02-12 5 views
0

У меня аналогичная проблема с одной здесь (dataframe by index and by integer)панда dataframe по логическому значению, по индексу, и целые

То, что я хочу, чтобы получить часть DataFrame булевской индексации (легко) и посмотрят на несколько значений назад, скажем, по предыдущему индексу и, возможно, еще несколько. К сожалению, предложенный ответ в связанном вопросе с 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 cceeding строки сдвинуты на фиксированную величину, вы могли бы использовать mask.shift сдвигать маску:

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

Если вы хотите выбрать lookback предшествующей строку, то вы могли бы расширить маску unioning ее со своими сдвигами:

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

или, что то же самое, используйте cumsum:

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

for-loop понятнее, но cumsum ехр Раньше быстрее, особенно если 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-backback: m] '(я предполагаю, что вторая форма немного быстрее, поскольку она специализирована для целых индексов). Я буду играть с вашим логическим подходом к сдвигу индекса. –

+0

Спасибо за 'np.flatnonzero' –

Смежные вопросы