【问题标题】:Get average of a list of times and compare average to a goal time获取时间列表的平均值并将平均值与目标时间进行比较
【发布时间】:2022-01-08 18:23:38
【问题描述】:

我正在尝试

  1. 从 df 列中的唤醒时间列表中获取平均唤醒时间,然后
  2. 将它们与目标唤醒时间(更早或更晚)进行比较
import pandas as pd

#convert to datetime object
df['wakeup_time_date']=pd.to_datetime(df['wakeup_time_date'], infer_datetime_format=True)

#extract time
df['wakeup_time']=df['wakeup_time_date'].dt.time

#below doesn't work as the object is no longer a datetime object
df['wakeup_time'].mean()

最后,我想将平均唤醒时间与早上 6:30 进行比较,并确定是早还是晚。

【问题讨论】:

标签: python pandas datetime


【解决方案1】:

正如MrFuppes 建议的那样,可能最简单的方法是转换为datetime.timedeltas,而不是datetime.times:

from datetime import datetime, timedelta, time
df = pd.DataFrame({"wakeup_time_date": ["2019/03/04 07:08:58", "2019/03/05 08:08:48", "2019/03/06 10:00:12", "2019/03/10 6:35:32"]})

df['wakeup_time_date']=pd.to_datetime(df['wakeup_time_date'])
df['time'] = df['wakeup_time_date'] - df['wakeup_time_date'].dt.normalize()
mean_td = df['time'].mean()

#Timedelta('0 days 07:58:22.500000')

现在,如果您不介意在 timedeltas 上进行操作,您可以直接进行比较:

goal_td = timedelta(hours=6, minutes=30) 
is_mean_later_than_goal = mean_td > goal_td
# True

或将其转换为 datetime.time 并以这种方式进行比较:

mean_time = (datetime.min + mean_td).time()
goal_time = time(hour=6, minute=30)
is_mean_later_than_goal = mean_time > goal_time
# True

【讨论】:

    【解决方案2】:

    这是一个使用 np.where() 的玩具示例,其中 True 行的时间大于 390 分钟(上午 6:30)且小于 720 分钟(例如中午,选择可仲裁性)。首先,使用 dt 属性创建分钟列。

    如果没有看到您的数据很难说,但如果您有“df 列中的唤醒时间列表”,我可能会设置一个 DatetimeIndex,然后在 np.where 之前对其进行平均时间聚合的 groupby () 步骤。

    from pandas import Timestamp
    import pandas as pd
    
    toy_dict = {'wakeup_time_date': {0: Timestamp('2021-11-11 13:04:44.342843'),
      1: Timestamp('2021-11-11 15:43:40.654980'),
      2: Timestamp('2021-11-11 17:31:07.409101'),
      3: Timestamp('2021-11-11 22:19:14.394725'),
      4: Timestamp('2021-11-12 09:03:41.957619'),
      5: Timestamp('2021-11-12 09:46:24.849156'),
      6: Timestamp('2021-11-12 10:45:07.950917'),
      7: Timestamp('2021-11-12 12:27:48.189281'),
      8: Timestamp('2021-11-12 12:57:27.112832'),
      9: Timestamp('2021-11-12 14:06:17.432817')}}
    
    
    df = pd.DataFrame(toy_dict)
    
    df['minutes'] = df['wakeup_time_date'].dt.hour * 60 + df['wakeup_time_date'].dt.minute + df['wakeup_time_date'].dt.second/60
    
    df['past_six_thirty'] = np.where((df['minutes'] > 390) & (df['minutes'] < 720), True, False)
    
    print(df)
    
        wakeup_time_date            minutes     past_six_thirty
    0   2021-11-11 13:04:44.342843  784.733333  False
    1   2021-11-11 15:43:40.654980  943.666667  False
    2   2021-11-11 17:31:07.409101  1051.116667 False
    3   2021-11-11 22:19:14.394725  1339.233333 False
    4   2021-11-12 09:03:41.957619  543.683333  True
    5   2021-11-12 09:46:24.849156  586.400000  True
    6   2021-11-12 10:45:07.950917  645.116667  True
    7   2021-11-12 12:27:48.189281  747.800000  False
    8   2021-11-12 12:57:27.112832  777.450000  False
    9   2021-11-12 14:06:17.432817  846.283333  False
    

    【讨论】:

    • 如果我正确理解了问题,OP 想比较平均唤醒时间,而不是每次。
    • @DanielWlazło 这就是为什么我建议在 np.where() 之前使用 groupby DatetimeIndex 步骤。我认为这种方法会更干净,除非 OP 对每个日期都有一堆数据框,但即便如此,我也可能会将它们连接起来。
    • 好吧,我的错,我查看了代码。我在你的回答中错过了这一点。
    • 一切顺利,@DanielWlazło!
    猜你喜欢
    • 2015-05-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多