我有一个具有下一个结构的时间序列数据帧:
Loc | Event | Start | End |
A | aaa |2018-08-30 00:26:29 |2018-08-30 00:26:59|
A | aaa |2018-08-30 00:26:30 |2018-08-30 00:26:47|
A | aaa |2018-08-30 00:38:05 |2018-08-30 00:39:09|
A | aaa |2018-08-30 00:40:31 |2018-08-30 00:40:41|
A | aaa |2018-08-30 00:57:17 |2018-08-30 00:57:28|
A | aaa |2018-08-30 00:57:36 |2018-08-30 00:58:07|
A | aaa |2018-08-30 00:57:53 |2018-08-30 00:59:23|
A | aaa |2018-08-30 00:57:58 |2018-08-30 00:58:11|
A | aaa |2018-08-30 00:58:00 |2018-08-30 00:58:08|
A | aaa |2018-08-30 01:27:58 |2018-08-30 01:28:58|
我的目标是根据事件之间的间隔将一组事件汇总为一个事件。从上面的示例中可以看到,有许多记录持续几秒钟,并且也在几秒钟之内生成。此类事件必须合并为一个,以组中第一个事件的开始时间和组中最后一个事件的最后时间为准。
结果,必须实现下一个输出:
Loc | Event | Start | End |
A | aaa |2018-08-30 00:26:29 |2018-08-30 00:26:59|
A | aaa |2018-08-30 00:26:30 |2018-08-30 00:26:47|
A | aaa |2018-08-30 00:38:05 |2018-08-30 00:39:09|
A | aaa |2018-08-30 00:40:31 |2018-08-30 00:40:41|
A | aaa |2018-08-30 00:57:17 |2018-08-30 00:58:08|
A | aaa |2018-08-30 01:27:58 |2018-08-30 01:28:58|
现在,我设法通过许多其他变量和for循环实现了这一目标,而且速度相当慢。因此,任何关于如何使用 pandas 方法实现此目标的想法都非常受欢迎。
要解决此问题,您需要:
您可以在这里(代码中的一些注释):
import pandas as pd
from io import StringIO
from dateutil.relativedelta import relativedelta
data = StringIO("""
Loc|Event|Start|End
A|aaa|2018-08-30 00:26:29|2018-08-30 00:26:59
A|aaa|2018-08-30 00:26:30|2018-08-30 00:26:47
A|aaa|2018-08-30 00:38:05|2018-08-30 00:39:09
A|aaa|2018-08-30 00:40:31|2018-08-30 00:40:41
A|aaa|2018-08-30 00:57:17|2018-08-30 00:57:28
A|aaa|2018-08-30 00:57:36|2018-08-30 00:58:07
A|aaa|2018-08-30 00:57:53|2018-08-30 00:59:23
A|aaa|2018-08-30 00:57:58|2018-08-30 00:58:11
A|aaa|2018-08-30 00:58:00|2018-08-30 00:58:08
A|aaa|2018-08-30 01:27:58|2018-08-30 01:28:58
""")
# load data into data frame
df = pd.read_csv(data, sep='|')
# convert string to datetime
df['Start'] = pd.to_datetime(df['Start'])
df['End'] = pd.to_datetime(df['End'])
def get_result(df_filtered):
df2 = pd.DataFrame({'Loc':df_filtered['Loc'].unique(), 'Event':df_filtered['Event'].unique(), 'Start':df_filtered['Start'].min(), 'End':df_filtered['End'].max()})
start_end = df_filtered['Start'].max()
return df2, start_end
# get datetime group range
min_datetime = df['Start'].min()
max_datetime = min_datetime + relativedelta(minutes=6)
# define variables for while loop
end_end = df['Start'].max()
start_end = min_datetime
results_list = []
while end_end > start_end:
# filter rows by dates
df_filtered = df[(df['Start'] >= min_datetime) & (df['End'] < max_datetime)]
# get result and new start datetime
df2, start_end = get_result(df_filtered)
# get new values for max and min datetime
df_start = df[df['Start'] > start_end]
min_datetime = df_start['Start'].min()
max_datetime = min_datetime + relativedelta(minutes=6)
# append df with results
results_list.append(df2)
df = pd.concat(results_list)
输出:
Loc Event Start End
0 A aaa 2018-08-30 00:26:29 2018-08-30 00:26:59
0 A aaa 2018-08-30 00:38:05 2018-08-30 00:40:41
0 A aaa 2018-08-30 00:57:17 2018-08-30 00:59:23
0 A aaa 2018-08-30 01:27:58 2018-08-30 01:28:58
滑稽。它适用于示例数据,但是当我尝试使用“真实”数据重现它时,它返回空数组或抛出“数组必须都具有相同长度”的错误,尽管它们的长度相同。 !那真的帮了我
@Ison不客气!使用此错误检查您的数据是否没有任何隐藏的白色字符串符号。
大声笑,不幸的是,我对熊猫知之甚少,无法说明为什么这样做,但是至少在目前,避免在loc和event中使用unique()方法解决了该问题。