Как правильно расположить строки между нужными днями? - PullRequest
1 голос
/ 20 октября 2019

Итак, у меня есть фрейм данных, который имеет:

  • Objects;
  • Сигналы тревоги;
  • Дата и время начала;
  • Дата окончания / время;

И выглядит так:

Object | Alarm | Start              | End                |                 
 obj1  | cell  | 2014-01-04 16:07:07| 2014-01-04 16:11:07|
 obj1  | loc   | 2014-01-04 16:08:07| 2014-01-04 16:09:07|
 obj1  | dc    | 2014-01-04 16:11:08| 2014-01-04 16:12:07| 
 obj1  | bat   | 2014-01-04 16:12:07| 2014-01-04 16:13:07| 
 obj2  | cell  | 2014-01-04 16:12:07| 2014-01-04 16:15:07| 
 obj2  | loc   | 2014-01-04 16:16:07| 2014-01-04 16:17:07| 
 obj2  | cell  | 2014-01-04 16:17:07| 2014-01-04 16:19:07| 
 obj2  | bat   | 2014-01-04 16:17:07| 2014-01-04 16:18:07| 
 obj3  | loc   | 2014-01-04 16:07:07| 2014-01-04 16:07:07| 
 obj3  | dc    | 2014-01-04 16:07:07| 2014-01-04 16:07:07| 

Я хочу удалить все тревоги для каждого объекта, возникшие между началом тревоги ячейки и концом ячейкитревога. Таким образом, результирующий кадр данных должен выглядеть следующим образом:

Object | Alarm | Start              | End                |                     
 obj1  | dc    | 2014-01-04 16:05:07| 2014-01-04 16:06:07|     
 obj1  | bat   | 2014-01-04 16:12:07| 2014-01-04 16:13:07|   
 obj2  | loc   | 2014-01-04 16:16:07| 2014-01-04 16:17:07|   
 obj3  | loc   | 2014-01-04 16:07:07| 2014-01-04 16:07:07| 
 obj3  | dc    | 2014-01-04 16:07:07| 2014-01-04 16:07:07| 

Я пытался сделать что-то вроде

for obj in data['Object'].unique():
    dt = data[data['Object']==obj]
    start = dt[dt['Alarm']=='cell']['Start']  
    end = dt[dt['Alarm']=='cell']['End']
    mask = (dt['Start'] >= start) & (dt['End'] <= end)
    dt.loc[~mask]  

Однако я получаю сообщение об ошибке плюс, я не могу понять, какполучить результат для всего кадра данных.

1 Ответ

1 голос
/ 20 октября 2019

Давайте попробуем использовать IntervalIndex и listcomp. Создайте идентификатор группы s для каждой группы, начинающейся с cell. Вызовите groupby.groups on Object и s, чтобы вернуть словарь, в котором каждое значение является массивом индекса группы. Создайте IntervalIndex iix из столбцов Start и End. Вызовите listcomp для значений словаря и передайте каждый массив индекса в iix, чтобы проверить overlaps, и объедините результат с маской m. Создайте маску m1, чтобы проверить, что группа Object не имеет значения cell. Наконец, нарезать df на m | m1

s = (df.Alarm.eq('cell') & df.Alarm.ne('cell').shift(-1, fill_value='True')).cumsum()
d = s.groupby([df.Object, s]).groups
iix = pd.IntervalIndex.from_arrays(df.Start, df.End, closed='both')
m = np.concatenate([~iix[x].overlaps(iix[x[0]]) for x in d.values()])
m1 = df.groupby(df.Object).Alarm.transform(lambda x: x.ne('cell').all())

df[m | m1]

Out[187]:
  Object Alarm               Start                 End
2   obj1    dc 2014-01-04 16:11:08 2014-01-04 16:12:07
3   obj1   bat 2014-01-04 16:12:07 2014-01-04 16:13:07
5   obj2   loc 2014-01-04 16:16:07 2014-01-04 16:17:07
8   obj3   loc 2014-01-04 16:07:07 2014-01-04 16:07:07
9   obj3    dc 2014-01-04 16:07:07 2014-01-04 16:07:07
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...