2015-03-18 2 views
1

У меня есть временные ряды событий, и я хотел бы считать предыдущие непоследовательные появления каждого типа событий в временных рядах. Я хочу сделать это с помощью панд. Я мог бы сделать это, итерации через предметы, но мне интересно, есть ли умный способ сделать это без петель.Найти повторяющиеся события во временных рядах с помощью pandas

Чтобы сделать его более ясным. Рассмотрим следующий временной ряд:

dates = pd.date_range('1/1/2011', periods=4, freq='H') 
data = ['a', 'a', 'b', 'a'] 
df = pd.DataFrame(data,index=dates,columns=["event"]) 

        event 
2011-01-01 00:00:00 a 
2011-01-01 01:00:00 a 
2011-01-01 02:00:00 b 
2011-01-01 03:00:00 a 

Я хотел бы добавить новый столбец, который говорит, для каждого элемента в столбце «событие», сколько непоследовательных раз ранее появился этот элемент. То есть, что-то вроде этого:

    event #prev-occurr 
2011-01-01 00:00:00 a  0 
2011-01-01 01:00:00 a  0 
2011-01-01 02:00:00 b  0 
2011-01-01 03:00:00 a  1 
+0

Для того, чтобы быть ясным, я следую за вами, какой вывод вы хотите, если столбец событий был «[», «a», «a», «b», А "]'? – DSM

+0

@DSM В этом случае вывод должен быть «[» 0 »,« 0 »,« 0 »,« 1 »,« 1 »,« 1 »,« 2 »]'. – Humberto

ответ

2

Мы на самом деле не имеют хорошую поддержку groupby для смежных групп, но мы можем использовать шаблон сдвига сравнения-cumsum, а затем плотный ранг, чтобы получить то, что вам нужно, IIUC:

>>> egroup = (df["event"] != df["event"].shift()).cumsum() 
>>> df["prev_occur"] = egroup.groupby(df["event"]).rank(method="dense") - 1 
>>> df 
        event prev_occur 
2011-01-01 00:00:00  a   0 
2011-01-01 01:00:00  a   0 
2011-01-01 02:00:00  b   0 
2011-01-01 03:00:00  a   1 
2011-01-01 04:00:00  a   1 
2011-01-01 05:00:00  b   1 
2011-01-01 06:00:00  a   2 

Это работает, потому что мы получаем непрерывный подсчет группы событий:

>>> egroup 
2011-01-01 00:00:00 1 
2011-01-01 01:00:00 1 
2011-01-01 02:00:00 2 
2011-01-01 03:00:00 3 
2011-01-01 04:00:00 3 
2011-01-01 05:00:00 4 
2011-01-01 06:00:00 5 
Freq: H, Name: event, dtype: int64 

, а затем мы можем сгруппировать это по типам событий, давая нам нон-место версия:

>>> for k,g in egroup.groupby(df["event"]): 
...  print(g) 
...  
2011-01-01 00:00:00 1 
2011-01-01 01:00:00 1 
2011-01-01 03:00:00 3 
2011-01-01 04:00:00 3 
2011-01-01 06:00:00 5 
Name: event, dtype: int64 
2011-01-01 02:00:00 2 
2011-01-01 05:00:00 4 
Name: event, dtype: int64 

, который мы можем, наконец, сделать густую ранг на.

+0

Большое спасибо @DSM! То есть, как я просил, действительно умный способ сделать то, что мне нужно :-) Я не знал, что можно группировать так, как вы. Если я правильно понимаю, это похоже на объединение столбцов 'df' и' egroup', group в столбце 'event', а затем удаление' df'columns. Правильно? – Humberto

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