如何根据时间条件进行 cumsum - resample pandas?

How to do cumsum based on a time condition - resample pandas?

我有一个如下所示的数据框

df = pd.DataFrame({
   'subject_id':[1,1,1,1,1,1],
   'time_1' :['2173-04-03 10:00:00','2173-04-03 10:15:00','2173-04-03 
              10:30:00','2173-04-03 10:45:00','2173-04-03 11:05:00','2173- 
              04-03 11:15:00'],
   'val' :[5,6,5,6,6,6]
})

我想找出一个值按顺序出现的总持续时间。下面的例子将帮助你理解

从上面的屏幕截图中,您可以看到 610:4523:59 依次出现,而其他值(尽管可以是实时的任何值)不是按顺序排列。

我做了类似的事情但没有给出预期的输出。它累加所有值

df['time_1'] = pd.to_datetime(df['time_1'])
df['seq'] = df['val'] == df['val'].shift(-1)

s=pd.to_timedelta(24,unit='h')-(df.time_1-df.time_1.dt.normalize())
df['tdiff'] =df.groupby(df.time_1.dt.date).time_1.diff().shift(-1).fillna(s).dt.total_seconds()/3600
df.groupby([df['seq'] == True])['tdiff'].cumsum() # do cumulative sum only when the values are in sequence

如何根据条件对组进行累加?

我希望我的输出如下所示。您看到 13:15 是因为我们在下一个 13:15 小时的数据中没有看到任何其他值,从第一次出现 6 开始 10:4524:00 hr - 10:45给出 13:15)

测试数据帧

df = pd.DataFrame({
     'subject_id':[1,1,1,1,1,1,1,1,1,1,1],
     'time_1' :['2173-04-03 12:35:00','2173-04-03 12:50:00','2173-04-03 
     12:59:00','2173-04-03 13:14:00','2173-04-03 13:37:00','2173-04-04 
     11:30:00','2173-04-05 16:00:00','2173-04-05 22:00:00','2173-04-06 
     04:00:00','2173-04-06 04:30:00','2173-04-06 08:00:00'],
     'val' :[5,5,5,5,10,5,5,8,3,4,6]
   })

IIUC,试试:

m=df.groupby(df.val.ne(df.val.shift()).cumsum()).first().rename_axis(None)
c=pd.to_timedelta(24,unit='h')-(m.time_1-m.time_1.dt.normalize())
final=m.assign(cumsum=m.time_1.diff().shift(-1).fillna(c))

   subject_id              time_1  val   cumsum
1           1 2173-04-03 10:00:00    5 00:15:00
2           1 2173-04-03 10:15:00    6 00:15:00
3           1 2173-04-03 10:30:00    5 00:15:00
4           1 2173-04-03 10:45:00    6 13:15:00

详情

df.val.ne(df.val.shift()).cumsum() 评估值是否每行都更改,并将相同的值分组到一个组中。

基于这个组,我们分组并获得每个组的第一个条目。然后我们从 time_1 中找到 diff() 并向上移动 1 位以对齐到顶部索引。 fillna 与 24 小时不同。

1) 首先,您应该将您的列时间转换为日期时间:

df.time_1 = pd.to_datetime(df.time_1)

2) 然后你可以按连续的重复值分组:

df['val_groups'] = (df.val != df.val.shift()).cumsum()

3) 另外,你需要每组到下一个值的时间:

df['time_till_next_val'] = df.time_1.diff().shift(-1)

4) 接下来将按连续值组分组并计算您的 consum 列:

 cols = ['subject_id', 'time_1', 'val', 'consum']
 df_consum = df.groupby(['subject_id', 'val', 'val_groups']).agg(consum=('time_till_next_val', 'sum'), time_1=('time_1', 'first')).reset_index()[cols]

5) 计算最后一组的 consum

last_start_time_group = df.time_1.iloc[df.val_groups.eq(df.val_groups.max()).idxmax()]
last_start_time_group = pd.to_timedelta(last_start_time_group.strftime('%H:%M:%S'), unit='d')
last_group_consum = pd.Timedelta(hours=24) - last_start_time_group

df_consum.consum.iloc[-1] = last_group_consum
df_consum

输出: