如果时间戳在较早时间戳的 14 小时内,是否删除它取决于是否删除较早的时间戳?这个答案考虑了这个问题的答案是“是”的情况。 (如果答案是“否”,那么下面测试数据的结果解决方案将只是第一个时间戳)。
设置
测试数据:
import pandas as pd
timestamps = pd.Series([0, 6,10,14,16,29,33,45,46]).apply(pd.Timedelta, unit="hours") + pd.Timestamp("2022")
timestamps 看起来像这样:
0 2022-01-01 00:00:00
1 2022-01-01 06:00:00
2 2022-01-01 10:00:00
3 2022-01-01 14:00:00
4 2022-01-01 16:00:00
5 2022-01-02 05:00:00
6 2022-01-02 09:00:00
7 2022-01-02 21:00:00
8 2022-01-02 22:00:00
dtype: datetime64[ns]
我们的目标解决方案包括第 1、4、6 和 8 个时间戳。
解决方案
此解决方案将使用piso(pandas 间隔集操作)包。这个想法是为每个时间戳创建一个 14 小时窗口,即间隔,并迭代地删除属于较早开始的间隔的时间戳。
import piso
# sort timestamps if not already sorted
timestamps = timestamps.sort_values()
# create 14 hour windows for each timestamp. Can be left-closed or right-closed, but not both
intervals = pd.IntervalIndex.from_arrays(timestamps, timestamps+pd.Timedelta("14h"))
# create the "disjoint adjacency matrix", which indicates pairwise if intervals are disjoint
mat = piso.adjacency_matrix(intervals, edges="disjoint")
mat 将是一个数据框,其索引和列是timestamps。 mat.values 是这样的
array([[False, False, False, True, True, True, True, True, True],
[False, False, False, False, False, True, True, True, True],
[False, False, False, False, False, True, True, True, True],
[ True, False, False, False, False, True, True, True, True],
[ True, False, False, False, False, False, True, True, True],
[ True, True, True, True, False, False, False, True, True],
[ True, True, True, True, True, False, False, False, False],
[ True, True, True, True, True, True, False, False, False],
[ True, True, True, True, True, True, False, False, False]])
将此矩阵的对角线设置为真
mat.iloc[range(len(mat)),range(len(mat))] = True
我们将从第一个间隔开始。从mat 的第一行可以推断出需要删除第二个和第三个区间。所以我们过滤掉这些区间对应的行和列,然后移动下一个区间(行),以此类推,直到到达最后一行。请注意,我们不需要检查最后一行的任何交叉点。
i = 0
while i < len(mat) -1:
mat = mat.loc[mat.iloc[i],mat.iloc[i]]
i+=1
结果将是一个数据框,其值全部为 True。更重要的是,索引(和列)将是间隔,其左端点是删除 14 小时内的时间戳后剩余的时间戳。
即pd.Series(mat.index.left)给了
0 2022-01-01 00:00:00
1 2022-01-01 14:00:00
2 2022-01-02 05:00:00
3 2022-01-02 21:00:00
dtype: datetime64[ns]
您可以使用 pandas.Series.isin 过滤您的原始数据框
注意:我是 piso 的创造者。如果您有任何反馈或问题,请随时与我们联系。