【发布时间】:2020-09-25 15:22:41
【问题描述】:
所以我有一个这样的数据框:
Start Time End Time IDs
15:02:13 15:10:24 BAMB30
19:46:19 19:46:29 BHI110
19:47:01 19:57:04 BHI110
19:47:01 19:56:58 BHI110
19:47:01 19:56:59 BHI110
12:01:46 12:06:30 AKB286
我想将行分组或(行中的 ID)组合成一个名为“events”的东西,其定义如下:
-
一个事件的开始时差应该是
-
一个事件的结束时间差应该是
-
每个事件的 C1、C2 列中的值相同。
-
每个事件中的不同/唯一 ID。
-
仅当基于 1 和 2 的组大小>5 时,事件才有效。
所以我想要的最终结果是这样的:
Start Time End Time IDs Event
15:02:13 15:10:24 BAMB30
19:46:19 19:46:29 BHI110
19:47:01 19:57:04 BHI110 1
19:47:01 19:56:58 BHI110 1
19:47:01 19:56:59 BHI110 1
12:01:46 12:06:30 AKB286
我们想为事件提供数字。例如,如果某些行属于某个事件,我们将为事件列中的所有这些行赋予相同的编号。
那么如何进行呢?
编辑:
我按照您的建议尝试了代码:
def tDlt(row):
st, et, sid, c1, c2 = row[['Start Time (HHMM)', 'End Time (HHMM)', 'IDs', 'C1', 'C2']]
if(tDlt.start is None):
tDlt.start, tDlt.end, tDlt.id, tDlt.c1, tDlt.c2, tDlt.ev = st, et, sid, c1, c2, 0
else:
if(((st - tDlt.start).total_seconds() > 120) or ((et - tDlt.end).total_seconds() > 120) or (sid == tDlt.id) or (c1!=tDlt.c1) or (c2!=tDlt.c2)):
tDlt.start, tDlt.end, tDlt.id, tDlt.c1, tDlt.c2 = st, et, sid, c1, c2
tDlt.ev += 1
return tDlt.ev
def gen_events():
global df
global sizeLimit
x = list(df['Start Time (HHMM)'])
y = list(df['End Time (HHMM)'])
for i in range(len(x)):
x[i] = str(x[i])
for i in range(len(y)):
y[i] = str(y[i])
df['Start Time (HHMM)'] = x
df['End Time (HHMM)'] = y
df['Start Time (HHMM)'] = df['Start Time (HHMM)'].apply(pd.Timedelta)
df['End Time (HHMM)'] = df['End Time (HHMM)'].apply(pd.Timedelta)
tDlt.start = None
ev = df.sort_values(['Start Time (HHMM)', 'End Time (HHMM)','IDs']).apply(tDlt, axis=1)
ev = ev.groupby(ev).transform(lambda grp: str(grp.iloc[0]) if grp.size > sizeLimit else '')
df['Event'] = ev[ev != ''].groupby(ev, sort=False).ngroup() + 1
df.Event.replace(np.nan, '', inplace=True)
df = df.dropna(how='all')
fs = filedialog.asksaveasfilename(filetypes=[("Excel files", ".xlsx .xls .xlsm"),("CSV files", ".csv")])
if((str(fs))[-3:] == "csv"):
df.to_csv(fs)
else:
df.to_excel(fs)
done()
注意:我需要按不同的IDS(不一样)对事件进行分组,这就是我将(sid == tDlt.id)放在代码的else条件中的原因。
如您所见,我希望单个事件具有不同的 ID,但它仍然使用一些相同的 ID 进行分组。代码哪里出错了?
注意:这些不是我的数据框中唯一的列。但是,在查找事件时,只有上述列很重要。 谢谢!
【问题讨论】:
-
在您的预期结果中,您没有在组 1 中包含“19:47:01 19:56:59”行。为什么?另一个细节:这个组只有 2 行,但您希望一个事件至少包含 5 行。
-
请更好地解释您的标准
-
您的代码仅将组中的每一行与上一个行进行比较。但我认为: 1. 源组应首先按开始时间和结束时间排序(您的数据样本未排序)。 2. 一个组应该在一些“初始”行(不一定是第一个)中包含两个时间都在给定限制内的开始/结束时间的行。还要写出单个组(按ID)是否可以包含多个事件。
-
@Valdi_Bo "19:47:01 19:56:59",是的,抱歉,这也将包括在内。是的,它必须包含至少 5 行才能称为事件。我需要一个大数据框来说明这一点。我已经编辑过了。是的,单个组可以包含多个事件,因为每一行都可以重叠成 >1 个组。
-
@gtomer 我们需要将行分组为事件。每组的长度应大于 5,并且组的每一行的开始时间和结束时间最多相差 2 分钟(绝对差异)。