【问题标题】:How to capture data within a given time frame based on an hour basis?如何以小时为单位在给定时间范围内捕获数据?
【发布时间】:2022-01-06 18:15:17
【问题描述】:

我仍在学习 Python,有时我的编码效率不是很高。我正在寻找一种更有效的方法来按“每小时”对数据输入进行充分分组。这是测量每小时的生产量,而不是每小时生产量的平均值(是的,我知道这要简单得多。举个例子,如果我在 4:30-5:30 和 5:30-6 之间做了 32 次:30 我做了 58 次,这两个时间框架不会是每小时生产的平均值,但会保持不变,这是我需要的。它必须适合的时间框架是 (4:30-5:30, 5:30-6:30, 6:30-7:30, 7:30-8:30, 8:30-9:30, 9:30-10:30, 11:00-12:00, 12:00-1:00, 1:00-2:00, 2:00-3:00, 3:00-4:00, 4:00-5:00, 5:00-6:00, 6:00-7:00, 7:30-8:30, 8:30-9:30, 9:30-10:30, 10:30-11:30, 11:30-12:30, 12:30-1:30)。我已经具有用于将数据输入 excel 的 GUI。我有两列标记为 *"Time" and "Date"Time 是我操纵小时和分钟的地方。

a_list = [2,3,4,5,6,7,8,9,10,11]
b_list = [11,12,13,14,15,16,17,18,19]
c_list = [19,20,21,22,23,0]
date = dt.datetime.now()
#hm =  float(date.strftime('%H.%M'))
#hour = float(date.strftime('%H'))
hour = float(5) #testing 
hm =  float(5.30) #testing
for i in a_list:
    if hour in a_list:
        if hour < 5:
            hour = 5
            a ="{:.2f}".format(hour) 
            print(f'Test 1:{a}')
            break
        if hour+.5 >= 5.5 and hour <10:
            if hm >= hour +.3:
                a ="{:.2f}".format(hour+1)
                print(f'Test 2: {a}')
            else: 
                a ="{:.2f}".format(hour) 
                print(f'Test 3: {a}')
        if hour >= 10: 
            hour = 10
            a ="{:.2f}".format(hour)
            print(f'Test 4: {a}')
    break

我还没有为其他列表添加任何代码。我正在寻找比这里更好的想法。我考虑了日期范围,但可能会遇到麻烦。这是其中两列的参考图片:

【问题讨论】:

  • 我建议在您的 excel 源数据中使用适当的时间戳值,并在您的 python 代码中使用datetime,而不是重新实现时间计算。除非这是您的目标(例如,出于教育目的)。
  • @blurryroots 我可能无法理解它,但在此之前我确实使用了日期时间,我无法按照我需要的方式对数据进行分组。我可能只是不知道这样做的方法,但例如 2022-01-06 4:30:00 和 2022-01-06 4:45:00 需要在 4:30-5:30 下组合在一起。我试图避免像上面的代码这样的 1000 个 if 语句以及具有较少“步骤”的语句。此表中还有其他列,而不仅仅是两列。

标签: python pandas python-datetime


【解决方案1】:

使用datetime 模块,当然可以避免繁琐的if-else 沙拉。 要创建时间窗口并在这些窗口中注册活动,让我们考虑以下事项:

import datetime

def calculate_slot(point_in_time, base, windows, length = datetime.timedelta(hours = 1)):
    '''Calculates the slot index of a given time relative to a base time and a list of time windows with a certain length.'''
    slot = -1
    # check if the time is further in the future than the end of the day.
    if (base + windows[-1] + length) <= point_in_time:
        return slot
    # increase the slot index, as long as the time is still bigger than the window time.
    while (slot+1) < len(windows) and (base + windows[slot+1]) < point_in_time:
        slot += 1

    return slot

def register_activity(activity_log, base, windows, point_in_time):
    '''Stores an entry in a slot depending on the point in time given.'''
    # in which window does the given time fit?
    slot = calculate_slot(point_in_time, base, windows)
    # only add if slot is valid.
    if -1 < slot:
        activity_log[slot].append(point_in_time)

def main():
    # when does the first time window start?
    base = datetime.datetime(2021, 1, 6)
    # what are the starting points of each window?
    windows = [
        datetime.timedelta(hours = 4, minutes = 30),
        datetime.timedelta(hours = 5, minutes = 30),
        datetime.timedelta(hours = 6, minutes = 30),
        datetime.timedelta(hours = 7, minutes = 30),
        datetime.timedelta(hours = 8, minutes = 30),
        datetime.timedelta(hours = 9, minutes = 30),
        datetime.timedelta(hours = 11, minutes = 00),
        datetime.timedelta(hours = 12, minutes = 00),
        datetime.timedelta(hours = 13, minutes = 00),
        datetime.timedelta(hours = 14, minutes = 00),
        datetime.timedelta(hours = 15, minutes = 00),
        datetime.timedelta(hours = 16, minutes = 00),
        datetime.timedelta(hours = 17, minutes = 00),
        datetime.timedelta(hours = 18, minutes = 00),
        datetime.timedelta(hours = 19, minutes = 30),
        datetime.timedelta(hours = 20, minutes = 30),
        datetime.timedelta(hours = 21, minutes = 30),
        datetime.timedelta(hours = 22, minutes = 30),
        datetime.timedelta(hours = 23, minutes = 30),
        datetime.timedelta(hours = 24, minutes = 30),
    ]

    # prepare the activity log with enought slots.
    activity_log = []
    for _ in range(0, len(windows)):
        activity_log.append([])

    # point in time to test against.
    search_time0 = datetime.datetime(2021, 1, 6, 8, 15)
    search_time1 = datetime.datetime(2021, 1, 6, 23, 42)
    search_time2 = datetime.datetime(2021, 1, 7, 1, 11)

    # register activity on specific times.
    register_activity(activity_log, base, windows, search_time0)
    register_activity(activity_log, base, windows, search_time1)
    register_activity(activity_log, base, windows, search_time2)

    # show activity log.
    print(activity_log)

if __name__ == '__main__':
    main()

这个概念是,定义一个基本时间(考虑的日子)并为每个窗口创建一个开始时间列表。使用timedelta,窗口由相对于开始时间的时间距离定义。

为了确定某个活动在某个时间属于哪个窗口/插槽,从最早到最晚检查这些窗口。

对于活动日志,使用列表列表(内部列表的数量等于窗口/插槽的数量)。注册活动时,计算给定时间的槽,如果找到槽,则将时间插入内部列表。

希望这可以为您的应用程序提供灵感。

【讨论】:

  • 谢谢,我很早就打算使用与此类似的方法,但我想我会尝试一些不同的方法,并想出了我上面的胡言乱语。我想我会检查社区的意见和我可能遇到的问题。
  • @Iamar249 我们都在旅途中。不要因为从 'gibbersih' 开始而感到难过,也不要把事情看得太个人化。希望您喜欢从答案中学习,就像我在给出答案时一样。如果一个人可以节省时间和资源,那么自己尝试(无论结果如何)然后与部落一起检查如何改进是非常有价值的,而不是仅仅跟随叙述 - 或者更糟 - 让别人否则在第一个地方为您完成所有工作。你做得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 2014-08-23
  • 2017-01-19
  • 1970-01-01
相关资源
最近更新 更多