Панды Python: как назначить последовательность чисел в виде столбца на основе фильтра?

#python #pandas #list #time-series

Вопрос:

Я пытаюсь назначить последовательный список номеров в виде столбца на основе фильтра для вызываемого фрейма данных о рабочем времени work ; цель состоит в том, чтобы создать уникальный идентификатор, привязанный к каждому началу концерта. Ниже приведен оригинальный набор с a gig_status column , который показывает, когда начинается концерт для работника в автомобиле:

    worker   veh   gig_status               starttime                stoptime
0  11133y  QQUK1     start            2018-12-21 15:17:29     2018-12-21 15:18:57
1  44706h  FF243     start            2019-01-01 00:10:16     2019-01-01 00:16:32
2  44706h  FF243                      2019-01-01 00:27:11     2019-01-01 00:31:38
3  44706h  FF243                      2019-01-01 00:46:20     2019-01-01 01:04:54
4  44761y  LL525     start            2019-01-01 00:19:06     2019-01-01 00:39:43
5  44842q  OO454     start            2019-01-01 00:12:35     2019-01-01 00:19:09
6  44842q  OO454                      2019-01-01 00:47:55     2019-01-01 01:00:01
7  44842q  OO454                      2019-01-01 01:12:47     2019-01-01 02:01:50
8  46090u  OP324     start            2019-01-01 00:16:23     2019-01-01 00:39:46
9  46090u  OP324                      2019-01-01 00:58:02     2019-01-01 01:19:02
 

Вот что я ожидаю от начального результата:

    worker       veh    gig_status          starttime                stoptime.      gig_id
0  11133y      QQUK1     start         2018-12-21 15:17:29     2018-12-21 15:18:57    1
1  44706h      FF243     start         2019-01-01 00:10:16     2019-01-01 00:16:32    2
2  44706h      FF243                   2019-01-01 00:27:11     2019-01-01 00:31:38   
3  44706h      FF243                   2019-01-01 00:46:20     2019-01-01 01:04:54
4  44761y      LL525     start         2019-01-01 00:19:06     2019-01-01 00:39:43    3
5  44842q      OO454     start         2019-01-01 00:12:35     2019-01-01 00:19:09    4
6  44842q      OO454                   2019-01-01 00:47:55     2019-01-01 01:00:01    
7  44842q      OO454                   2019-01-01 01:12:47     2019-01-01 02:01:50    
8  46090u      OP324     start         2019-01-01 00:16:23     2019-01-01 00:39:46    5
9  46090u      OP324                   2019-01-01 00:58:02     2019-01-01 01:19:02    
 

Идея состоит в том, чтобы использовать заполнение вперед, чтобы привязать каждую запись к ее новому идентификатору.

В R использовании data.table() это просто и написано примерно так:

 work[gig_status=="start", gig_id:=seq.Int(.N)]
 

В основном каждой записи присваивается последовательность, соответствующая значению «начало» в gig_status.

Как бы я достиг этого результата в python? Я пробовал использовать диапазон, но, похоже, он работает по-другому:

 #produce the length of the subset dataframe
x = len(work.loc[work.gig_status == 'start'])

#produce a listed range from 0 to that length and assign as a new column
work['gig_id'] = work.loc[work.gig_status == 'start'] = list(range(0,x)
 

В итоге я получаю gig_id, который не находится между 0 и длиной отфильтрованного набора данных.

Комментарии:

1. пустые места в gig_status-это символ NaN или пустой '' или ' ' ?

Ответ №1:

попробуйте через cumsum() и mask() :

 df['gig_id']=df['gig_status'].eq('start').cumsum().mask(df['gig_status'].isna())
#OR via where() but with opposite condition
df['gig_id']=df['gig_status'].eq('start').cumsum().where(df['gig_status'].notna())
 

или

через loc средство доступа и cumsum() :

 m=df['gig_status'].eq('start')
df.loc[df['gig_status'].notna() amp; m,'gig_id']=m.cumsum()
 

или

 #import numpy as np
df['gig_id']=np.where(df['gig_status'].isna(),np.nan,df['gig_status'].eq('start').cumsum())