根据日期范围创建包含分类变量的新列

时间:2020-02-14 15:23:03

标签: python pandas datetime time-series

如果我有这样的数据,其中包含一天的时间序列日期为一年(2019)-

datetime
0   15.02.19 13:00
1   15.02.19 14:00
2   15.02.19 15:00
3   15.02.19 16:00
4   15.02.19 17:00

并且我想创建一个新列,如果我的日期时间在一定范围内(2019年的学校假期日期)和“学期时间”,则该列的值为“学校假期”,否则我将如何以最有效的方式进行处理?结果数据框应如下所示-

datetime    school holiday
0   15.02.19 13:00  Term time
1   15.02.19 14:00  Term time
2   15.02.19 15:00  Term time
3   15.02.19 16:00  Term time
4   15.02.19 17:00  School Holiday

我的想法是,我会考虑学校放假的日期,就像这样:

Autumn Half Term Holidays   21 Oct 2019 - 25 Oct 2019
Winter Holidays             23 Dec 2019 - 3 Jan 2020
etc...

用这些日期制作字典,然后以某种方式使用lamba进行应用?本质上,该功能应为-如果datetime == holiday_range:“学校假期”,否则:“学期时间”。

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

也许这会有所帮助:

holidays = {'Autumn Half Term Holidays': ('16 Feb 2019', '25 Feb 2019')}
holidays_map = {date.date(): holiday for holiday, dates in holidays.items() for date in pd.date_range(*dates)}

df['holiday'] = df['datetime'].dt.date.map(holidays_map).fillna('Term time')

df

             datetime                    holiday
0 2019-02-15 13:00:00                  Term time
1 2019-02-15 14:00:00                  Term time
2 2019-02-15 15:00:00                  Term time
3 2019-02-15 16:00:00                  Term time
4 2019-02-16 17:00:00  Autumn Half Term Holidays

答案 1 :(得分:1)

您的DataFrame中的行可能比唯一的Holidays多。对于此类问题,您可能需要在某个地方循环播放,因此最好在较少的Holidays循环播放

将日期转换为datetime dtype,然后将假日存储在单独的DataFrame中,再次使用datetime dtype

import pandas as pd
df['datetime'] = pd.to_datetime(df['datetime'], format='%d.%m.%y %H:%M')

df2 = pd.DataFrame({'Holiday': ['Autumn Half Term Holidays', 'Winter Holidays'],
                    'start': pd.to_datetime(['2019-10-21', '2019-12-23']),
                    'end': pd.to_datetime(['2019-10-25', '2020-01-03'])})

现在要确定某天是否是假期,我们将检查日期时间是否在任意之间。地图只会获取您的标签,而不是正确/错误。鉴于您的假期,我在您的示例中添加了一行,只是为了说明它的工作原理。

df['holiday'] = (pd.concat([df['datetime'].between(start, end) for start,end in zip(df2.start, df2.end)], 1)
                   .any(1)
                   .map({True: 'School Holiday', False: 'Term time'}))

             datetime         holiday
0 2020-01-01 01:00:00  School Holiday
1 2019-02-15 13:00:00       Term time
2 2019-02-15 14:00:00       Term time
3 2019-02-15 15:00:00       Term time
4 2019-02-15 16:00:00       Term time
5 2019-02-15 17:00:00       Term time