python - 如何计算间隔序列中1小时间隔的总数?

标签 python pandas datetime 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), 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 小时:

  1. 12:30 + 1H -> 13:30(13:30 是在可用间隔之一内的时间戳。特别是在 13:05 - 13:50 内,这是一个间隔在我们的数据框中。然后,我们将从 13:30 开始继续。

  2. 13:30 + 1H -> 14:30(14:30 不包含在我们的任何 df 间隔中 - 我们选择 14:30 之后最接近的 start_time)

  3. 16:00 + 1H -> 17:00(17:00 不包含在我们数据帧的任何间隔中)

  4. 17:20 + 1H -> 18:20(18:20 包含在 17:45 - 18:30 之间,这也是我们数据框中的一个时间间隔)

  5. 18:20 + 1H -> 19:20(包含在我们的最后一个时段)

  6. 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_timestart_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/

相关文章:

Python如何提取pandas数据框中[]括号内的指定字符串并使用 bool 值创建一个新列

pandas - dask 读取 Parquet 并指定架构

javascript - Nodejs Mongoose : Trying to save date in UTC Timezone but its saving in local time zone

javascript - 使用 Javascript 将字符串(日期格式)转换为日期时间

python - Pandas 数据帧 : Operation per batch of rows

Python:从字符串数组中删除 np nan 值

c++ - SWIG - 命名空间问题

python - 当在 Python 中测试另一个线程的结果时,PyTest 测试套件在断言应该失败时通过?

javascript - JavaScript 中的日期增量

python - RGB 是从 ImageGrab.grab().load() 中获取的,是数组还是字符串