【问题标题】:Comparing 2 dataframes to add rows if between dates如果在日期之间比较 2 个数据框以添加行
【发布时间】:2021-07-02 13:02:43
【问题描述】:

这里是全新的,我尝试查找我的问题,但找不到任何类似的东西!

我正在尝试设置一个数据框,其中包含时间表及其活动类型的数据。例如,如果它是“1”,则表示正常活动,如果是“2”,则取消,并将该数据帧与另一个数据帧进行比较,以查看第一个数据帧中的开始/结束日期之间是否存在日期,如果有, 对其进行修改,使其变为 3 行而不是 1 行,第一个开始/结束日期行直到该假期,假期日期行,然后开始/结束日期在假期之后继续。

我在创建单个数据框时没有问题,但是当我想比较另一个系列/数据框并可能添加可能位于所述 StartDate 和 EndDate 之间的行时,我的问题就出现了。

示例 调度数据帧

Start Date End Date Activity Type
2021-01-01 2021-12-31 1

与其他数据框相比

Holiday Start Date Holiday End Date
2021-02-14 2021-02-14
2021-07-04 2021-07-05

结局是这样的:

Start Date End Date Activity Type
2021-01-01 2021-02-13 1
2021-02-14 2021-02-14 2
2021-02-15 2021-07-03 1
2021-07-04 2021-07-04 2
2021-07-05 2021-12-31 1

感谢任何帮助!

谢谢,S。

【问题讨论】:

  • Activity Type == 2是什么意思?您的 Schedule 数据框 不包含 Activity Type == 2,所以它实际上可能意味着“Activity Type == 2 在假期期间”?
  • 活动类型 2 意味着那一天是关闭的,所以是的,在假期期间它会是类型 2。

标签: python pandas date for-loop python-holidays


【解决方案1】:

为了展示一个更有启发性的例子,我创建了 Schedule 来包含 多行

  Start Date   End Date  Activity Type
0 2021-01-01 2021-05-31             10
1 2021-06-01 2021-12-31             20

我将假期创建为:

  Holiday Start Date Holiday End Date
0         2021-02-14       2021-02-14
1         2021-03-10       2021-03-12
2         2021-07-04       2021-07-06

所有日期列都是 datetime64 类型。

准备步骤是从假期创建一个IntervalIndex

ind = pd.IntervalIndex.from_arrays(Holidays['Holiday Start Date'],
    Holidays['Holiday End Date'], closed='both')

要从单行获取结果,请创建以下函数:

def getActivities(row):
    dd = pd.date_range(row['Start Date'], row['End Date'])
    ss = dd.to_series().apply(lambda dat: ind.contains(dat).any())
    s1 = ss[ss != ss.shift()]
    s2 = ss[ss != ss.shift(-1)]
    s1 = s1.astype(int) + row['Activity Type']
    rv = s1.astype(int).reset_index().rename(columns={'index': 'Start Date',
        0: 'Activity Type'})
    rv.insert(1, 'End Date', s2.index)
    return rv

要测试这个函数,你可以在一行上调用它,比如初始行:

getActivities(Schedule.iloc[0])

要完全了解所有详细信息,请在下面保存一行 Schedule 一个变量:

row = Schedule.iloc[0]

然后执行getActivities中的每条指令,查看中间结果。

要获得 all 行的预期结果,您必须连接 将此函数应用于每一行的结果:

pd.concat(Schedule.apply(getActivities, axis=1).values, ignore_index=True)

对于我的测试数据,结果是:

  Start Date   End Date  Activity Type
0 2021-01-01 2021-02-13             10
1 2021-02-14 2021-02-14             11
2 2021-02-15 2021-03-09             10
3 2021-03-10 2021-03-12             11
4 2021-03-13 2021-05-31             10
5 2021-06-01 2021-07-03             20
6 2021-07-04 2021-07-06             21
7 2021-07-07 2021-12-31             20

前 5 行来自 Schedule 的第 0 行,有 2 个假期。 最后 3 行来自第 1 行,有 1 个假期。

请注意,活动类型是原始值(对于“正常”期间) 或原始值 + 1(节假日),所以 Schedule 不应该 包含连续值作为活动类型

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 2019-04-30
    • 2019-10-14
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多