【问题标题】:Combine weekday with hours in Pandas在 Pandas 中结合工作日和小时
【发布时间】:2021-04-10 06:58:48
【问题描述】:

我有一个数据框,其中包含包含工作日名称的工作日列和包含这些天的小时数的时间列。如何组合这两列,以便它们也可以排序?

我已经尝试过字符串版本,但它无法根据工作日和小时进行排序。

这是示例表的外观。

weekday time
Monday 12:00
Monday 13:00
Tuesday 20:00
Friday 10:00

这就是我想要的。

weekday_hours
Monday 12:00
Monday 13:00
Tuesday 20:00
Friday 10:00

【问题讨论】:

标签: python pandas


【解决方案1】:

假设 df 是您的初始数据帧

import json
datas = json.loads(df.to_json(orient="records"))
final_data = {"weekday_hours": []}
for data in datas:
    final_data["weekday_hours"].append(data['weekday'] + ' ' + data['time'])
final_df = pd.DataFrame(final_data)
final_df

输出:

【讨论】:

    【解决方案2】:

    您首先需要按小时创建一个 7 天的日期时间对象以进行排序。在正常的数据仓库世界中,您通常有一个日历和一个时间维度,其中包含您可以合并和排序的日期数据的所有不同表示形式,这是对该方法的改编。

    import pandas as pd
    
    df1 = pd.DataFrame({'date' : pd.date_range('01 Jan 2021', '08 Jan 2021',freq='H')})
    df1['str_date'] = df1['date'].dt.strftime('%A %H:%M')
    
    print(df1.head(5))
    
        date      str_date
    0 2021-01-01 00:00:00  Friday 00:00
    1 2021-01-01 01:00:00  Friday 01:00
    2 2021-01-01 02:00:00  Friday 02:00
    3 2021-01-01 03:00:00  Friday 03:00
    4 2021-01-01 04:00:00  Friday 04:00
    

    然后创建要合并的列。

    df['str_date'] = df['weekday'] + ' ' +  df['time'] 
    
    df2 = pd.merge(df[['str_date']],df1,on=['str_date'],how='left')\
                                .sort_values('date').drop('date',1)
    
    
    print(df2)
    
     str_date
    3   Friday 10:00
    0   Monday 12:00
    1   Monday 13:00
    2  Tuesday 20:00
    

    【讨论】:

      【解决方案3】:

      根据我对问题的理解,您需要一个“weekday_hours”列,但您还希望能够根据此列对数据进行排序。这有点棘手,因为“星期一”没有提供足够的信息来定义有效的datetime。例如,使用pd.to_datetime(df['weekday_hours'], format='%A %H:%M' 进行解析,如果只给出工作日和时间,将返回1900-01-01 <hour::minute::second>。排序时,仅按时间排序。

      一种解决方法是使用dateutil 来解析日期。代替日期,它将返回对应于星期几的下一个日期。例如,今天(2021 年 4 月 9 日)dateutil.parser.parse('Friday 10:00') 返回 datetime.datetime(2021, 4, 9, 10, 0)dateutil.parser.parse('Monday 10:00') 返回 datetime.datetime(2021, 4, 12, 10, 0)。因此,我们需要将“默认”日期设置为与一周中的“第一”天相对应的日期。这是一个以未排序日期开头的示例:

          import datetime
      import dateutil
      import pandas as pd
      
      weekdays = ['Friday', 'Monday', 'Monday', 'Tuesday']
      times = ['10:00', '13:00', '12:00', '20:00', ]
      df = pd.DataFrame({'weekday' : weekdays, 'time' : times})
      
      df2 = pd.DataFrame()
      df2['weekday_hours'] = df[['weekday', 'time']].agg(' '.join, axis=1)
      
      amonday = datetime.datetime(2021, 2, 1, 0, 0) # assuming week starts monday
      sorter = lambda t: [dateutil.parser.parse(ti, default=amonday) for ti in t]
      print(df2.sort_values('weekday_hours', key=sorter))
      

      产生输出:

        weekday_hours
      2   Monday 12:00
      1   Monday 13:00
      3  Tuesday 20:00
      0   Friday 10:00
      

      请注意,如果您处理大量数据,则可能有更高效的计算方法,但这应该说明可排序的工作日/时间对的想法。

      【讨论】:

        猜你喜欢
        • 2020-10-12
        • 1970-01-01
        • 2018-02-14
        • 1970-01-01
        • 2023-02-07
        • 2022-01-07
        • 2022-01-20
        • 2017-10-24
        • 2017-05-23
        相关资源
        最近更新 更多