#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())