-1

在这里全新,我尝试查找我的问题,但找不到任何非常相似的东西!

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

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

示例计划数据框

开始日期 结束日期 活动类型
2021-01-01 2021-12-31 1

与其他数据框相比

假期开始日期 假期结束日期
2021-02-14 2021-02-14
2021-07-04 2021-07-05

结局是这样的:

开始日期 结束日期 活动类型
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。

4

1 回答 1

0

为了提供一个更有启发性的示例,我创建了包含 行的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类型。

一个准备步骤是从Holidays创建一个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中的每条指令并查看中间结果。

并且要获得所有行的预期结果,您必须将此函数的应用结果连接到每一行:

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 个假期。

请注意,Activity Type是原始值(对于“正常”期间)或原始值 + 1(对于假期期间),因此Schedule不应包含连续值作为Activity Type

于 2021-07-03T07:20:41.540 回答