2014-02-18 3 views
0

У меня есть Panadas DataFrame, содержащий измерения (Val) различных операций (OpID) с отметкой времени, когда произошло измерение (OpTime).pandas - определить продолжительность события

OpID    OpTime Val 
143 2014-01-01 02:35:02 20 
143 2014-01-01 02:40:01 24 
143 2014-01-01 02:40:03 0 
143 2014-01-01 02:45:01 0 
143 2014-01-01 02:50:01 20 
143 2014-01-01 02:55:01 0 
143 2014-01-01 03:00:01 20 
143 2014-01-01 03:05:01 24 
143 2014-01-01 03:10:01 20 
212 2014-01-01 02:15:01 20 
212 2014-01-01 02:17:02 0 
212 2014-01-01 02:20:01 0 
212 2014-01-01 02:25:01 0 
212 2014-01-01 02:30:01 20 
299 2014-01-01 03:30:03 33 
299 2014-01-01 03:35:02 33 
299 2014-01-01 03:40:01 34 
299 2014-01-01 03:45:01 33 
299 2014-01-01 03:45:02 34 

Мое желание генерировать вывод, который показывает только периоды времени, в течение которых измерение возвращало ноль. В столбце «Начало» будет показан первый в серии OpTimes, который привел бы к нулю, а End будет содержать OpTime первого Val, который был отличным от нуля.

Учитывая приведенные выше данные примеры мой желаемый результат:

OpID      Start      End 
143  2014-01-01 02:40:03  2014-01-01 02:50:01 
143  2014-01-01 02:55:01  2014-01-01 03:00:01 
212  2014-01-01 02:17:02  2014-01-01 02:30:01 
+1

Что делать, если последнее измерение в группе равна нулю? – DSM

+0

В идеале результат будет включать строку для этого либо с нулевым, NaN, либо с OpTime в столбце End. Я бы рассматривал этот случай как «дополнительный кредит», хотя для моих текущих потребностей правильный ответ не требовал бы обработки этого дела. –

ответ

1

Как насчет использования pivot()?

import numpy as np 
import pandas as pd 

df['Zeros'] = (df['Val']==0) 
df['Valdf'] = np.hstack((nan, diff(df['Zeros'].values))) #how do you treat the first cell? 
df['Valdr'] = np.hstack((diff(df['Zeros'].values), nan)) #how do you treat the last cell? 
pf2 = pd.concat([df[((df['Zeros']!=True)&(df['Valdf']==1))],df[((df['Zeros'])&(df['Valdr']==1))]]).sort_index() 
pf2['State'] = np.where(pf2['Zeros'], 'Start', 'End') 
pf2['idx2'] = pf2['OpID'] + np.arange(len(pf2))/2*0.00000001 #need unique index for .pivot() 
print pf2.pivot(index='idx2', columns='State', values='OpTime') 

State     End    Start 
idx2           
143.0 2014-01-01 02:50:01 2014-01-01 02:45:01 
143.1 2014-01-01 03:00:01 2014-01-01 02:55:01 
212.2 2014-01-01 02:30:01 2014-01-01 02:25:01 

Чтобы получить один вы представили, вероятно, просто:

pf3 = pd.DataFrame(pf2.pivot(index='idx2', columns='State', values='OpTime')) 
pf3.index=asarray(pf3.index.values, 'int') 
+0

Это решение зависит от предположения, что 'End' и' Start' встречаются парами в вашем временном ряду. Ситуация @DSM, безусловно, описывает ситуацию, которая нарушит это предположение. Кроме того, вам также может понадобиться подумать о том, что делать, когда первый момент времени равен нулю. Я не знаю, хотите ли вы рассматривать его как «start», потому что система может (потенциально) уже находиться в состоянии «val == 0», прежде чем вы начнете принимать измерения. Во всяком случае, всего несколько мыслей. Все зависит от вашего приложения и проблемы реального мира. –

+0

Отлично работает! Спасибо за помощь. Возможно, мне придется обработать эти крайние случаи первого и последнего измерений с нулем, поскольку я привожу больше данных, но это делает то, что мне нужно сейчас. Я сделал редактирование мультипликатора «уникальное значение», когда число 0,1 перекатилось, что вызвало проблемы, поэтому вместо этого я использовал 0,00000001. –

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