如何根据时间条件进行 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]
})
我想找出一个值按顺序出现的总持续时间。下面的例子将帮助你理解
从上面的屏幕截图中,您可以看到 6
从 10:45
到 23: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:45
(24: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
输出:
我有一个如下所示的数据框
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]
})
我想找出一个值按顺序出现的总持续时间。下面的例子将帮助你理解
从上面的屏幕截图中,您可以看到 6
从 10:45
到 23: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:45
(24: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
输出: