让我们考虑以下排序时间间隔的数据框:
import pandas as pd
from io import StringIO
s="""start_time,end_time
2022-01-01 12:30:00,2022-01-01 12:45:00
2022-01-01 13:05:00,2022-01-01 13:50:00
2022-01-01 14:00:00,2022-01-01 14:20:00
2022-01-01 16:00:00,2022-01-01 16:45:00
2022-01-01 17:20:00,2022-01-01 17:35:00
2022-01-01 17:45:00,2022-01-01 18:30:00
2022-01-01 19:00:00,2022-01-01 19:25:00"""
df = pd.read_csv(StringIO(s), sep=",")
df.start_time = pd.to_datetime(df.start_time)
df.end_time = pd.to_datetime(df.end_time)
start_time end_time
0 2022-01-01 12:30:00 2022-01-01 12:45:00
1 2022-01-01 13:05:00 2022-01-01 13:50:00
2 2022-01-01 14:00:00 2022-01-01 14:20:00
3 2022-01-01 16:00:00 2022-01-01 16:45:00
4 2022-01-01 17:20:00 2022-01-01 17:35:00
5 2022-01-01 17:45:00 2022-01-01 18:30:00
6 2022-01-01 19:00:00 2022-01-01 19:25:00
其想法是,1 小时间隔基本上按以下方式计算:
我们从第一个间隔的 start_time
开始,然后添加 1 小时。
如果生成的时间戳在数据帧中的以下间隔之一内,则我们通过向该新时间戳添加 1 小时等来重复该过程。
但是,如果生成的时间戳不在两个间隔内,而是在两个间隔之间,那么我们将继续在下一个间隔的 start_time
中添加 1 小时。
输入将是上面的数据框。
流程是:
我们首先在第一个间隔的 start_time
上添加 1 小时:
12:30 + 1H -> 13:30(13:30 是在可用间隔之一内的时间戳。特别是在 13:05 - 13:50 内,这是一个间隔在我们的数据框中。然后,我们将从 13:30 开始继续。
13:30 + 1H -> 14:30(14:30 不包含在我们的任何 df 间隔中 - 我们选择 14:30 之后最接近的
start_time
)16:00 + 1H -> 17:00(17:00 不包含在我们数据帧的任何间隔中)
17:20 + 1H -> 18:20(18:20 包含在 17:45 - 18:30 之间,这也是我们数据框中的一个时间间隔)
18:20 + 1H -> 19:20(包含在我们的最后一个时段)
19:20 + 1H -> 20:20(我们已达到或超过(大于或等于)上一个间隔的
end_time
,因此我们停止)。 例如,如果数据帧中的最后一个end_time
是 19:20:00 而不是 19:25:00,那么我们将在上一步中停止(因为我们达到了时间戳)大于或等于最后一个end_time
)。
输出:6
(在另一种情况下,最后一个 end_time
等于 19:20:00,输出将等于 5)。
输出代表加1H的过程重复的总次数。
就代码而言,我考虑过以某种方式使用 .shift()
但我不确定如何使用。问题是,当生成的时间戳不在可用间隔之间时,我们应该搜索最接近的以下 start_time
。
最佳答案
矢量化(即并行化)不太可能实现,因为每一步的过程都取决于前面步骤的计算结果。无论如何,解决方案都将是某种迭代。工作速度主要取决于您选择使用的算法。
在我看来,一个好的算法是查看相邻记录的 end_time
和 start_time
是否落入相同的小时步长就好像我们从某个点开始以小时为单位来测量长度。为此,我们可以使用整数除法:
import pandas as pd
from io import StringIO
s = """start_time,end_time
2022-01-01 12:30:00,2022-01-01 12:45:00
2022-01-01 13:05:00,2022-01-01 13:50:00
2022-01-01 14:00:00,2022-01-01 14:20:00
2022-01-01 16:00:00,2022-01-01 16:45:00
2022-01-01 17:20:00,2022-01-01 17:35:00
2022-01-01 17:45:00,2022-01-01 18:30:00
2022-01-01 19:00:00,2022-01-01 19:25:00"""
df = pd.read_csv(StringIO(s), parse_dates=[0, 1])
data = df.to_numpy().flatten()
start = data[0]
step = pd.Timedelta(1, 'H') # hour as a unit of length
count = 0
for x, y in data[1:-1].reshape(-1, 2):
# x is previous end_time
# y is next start_time
length = (x-start) // step + 1
if start + step*length < y:
count += length
start = y
integer, decimal = divmod((data[-1] - start) / step, 1)
count += integer if decimal == 0 else integer+1
print(f'{count = }')
关于python - 如何计算间隔序列中1小时间隔的总数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73913066/