如何获得数据框之间的总时间重叠?

时间:2019-12-12 11:17:25

标签: python pandas dataframe

说我有两个熊猫数据框:

import pandas as pd

df1 = pd.DataFrame(
    {
        "Start": {
            0: "2019-07-19 07:00:00",
            1: "2019-07-19 08:00:00",
            2: "2019-07-19 10:00:00",
        },
        "Finish": {
            0: "2019-07-19 07:30:00",
            1: "2019-07-19 08:30:00",
            2: "2019-07-19 10:30:00",
        },
    }
)

df2 = pd.DataFrame(
    {
        "Start": {0: "2019-07-19 07:30:00", 1: "2019-07-19 08:15:00",},
        "Finish": {0: "2019-07-19 08:00:00", 1: "2019-07-19 09:00:00",},
    }
)
df1.Start = pd.to_datetime(df1.Start)
df2.Finish = pd.to_datetime(df2.Finish)

它们看起来像这样:

|    | Start               | Finish              |
|---:|:--------------------|:--------------------|
|  0 | 2019-07-19 07:00:00 | 2019-07-19 07:30:00 |
|  1 | 2019-07-19 08:00:00 | 2019-07-19 08:30:00 |
|  2 | 2019-07-19 10:00:00 | 2019-07-19 10:30:00 |

|    | Start               | Finish              |
|---:|:--------------------|:--------------------|
|  0 | 2019-07-19 07:30:00 | 2019-07-19 08:00:00 |
|  1 | 2019-07-19 08:15:00 | 2019-07-19 09:00:00 |

这是我绘制它们的样子(每行StartFinish之间的颜色): enter image description here

请考虑一下,好像df1记录了TV1打开时的时间,而df2记录了TV2打开时的时间。我想找到任何电视打开的总时间。在上面的图中,这用行df1 or df2表示。

附录

这是我制作剧情的方式:

import plotly.figure_factory as ff

df3 = pd.DataFrame(
    {
        "Start": {0: "2019-07-19 07:00:00", 1: "2019-07-19 10:00:00",},
        "Finish": {0: "2019-07-19 09:00:00", 1: "2019-07-19 10:30:00",},
    }
)
df1['Resource'] = ['df1']*3
df2['Resource'] = ['df2']*2
df3['Resource'] = ['df1 or df2']*2
df1['Task'] = ['df1']*3
df2['Task'] = ['df2']*2
df3['Task'] = ['df1 or df2']*2

fig = ff.create_gantt(
    pd.concat([df1, df2, df3]).reset_index(drop=True),
    group_tasks=True,
    index_col="Resource",
)
fig.show()

这是我打印出数据框的地方:

from tabulate import tabulate

print(df1.pipe(tabulate, headers="keys", tablefmt="pipe"))
print(df2.pipe(tabulate, headers="keys", tablefmt="pipe"))

1 个答案:

答案 0 :(得分:2)

请注意,此处输入的内容基于原始问题。


我不确定这是否可以很好地完成,因为您总是在比较行,但是只有一种方法:

df1['start_time'] = pd.to_datetime(df1['start_time'])
df2['start_time'] = pd.to_datetime(df2['start_time'])
df1['end_time'] = pd.to_datetime(df1['end_time'])
df2['end_time'] = pd.to_datetime(df2['end_time'])

all_events = pd.concat((df1, df2)).sort_values('start_time')
result = all_events.iloc[0:1].copy()
for _, row in all_events.iterrows():
    if row['start_time'] <= result['end_time'].iloc[-1]:
        if row['end_time'] > result['end_time'].iloc[-1]:
            result['end_time'].iloc[-1] = row['end_time']
    else:
        result = result.append(row, ignore_index=True)

print(all_events)
print(result)

开始的部分只是让熊猫自己处理时间比较。基础知识:

  1. 创建所有事件的表格
  2. 按开始时间对其进行排序
  3. 将第一行添加到结果中
  4. 对于每个新行,开始时间是否早于最后添加的结束时间?
    • 是:如果新的结束时间大于上一个的结束时间,请对其进行更新。
    • 否:由于该行不相交,因此将该行作为新行添加到结果中。

表的结果(对所有事件和结果进行了排序):

             end_time          start_time
0 2019-07-19 06:07:10 2019-07-19 06:04:57
1 2019-07-19 06:27:41 2019-07-19 06:26:33
2 2019-07-19 06:35:43 2019-07-19 06:33:18
0 2019-07-19 06:35:53 2019-07-19 06:34:56
1 2019-07-19 06:37:45 2019-07-19 06:36:44
2 2019-07-19 06:40:11 2019-07-19 06:38:33
3 2019-07-19 06:40:25 2019-07-19 06:38:37
4 2019-07-19 07:02:20 2019-07-19 06:59:48
3 2019-07-19 07:06:47 2019-07-19 07:01:20
4 2019-07-19 07:09:19 2019-07-19 07:07:17
             end_time          start_time
0 2019-07-19 06:07:10 2019-07-19 06:04:57
1 2019-07-19 06:27:41 2019-07-19 06:26:33
2 2019-07-19 06:35:53 2019-07-19 06:33:18
3 2019-07-19 06:37:45 2019-07-19 06:36:44
4 2019-07-19 06:40:25 2019-07-19 06:38:33
5 2019-07-19 07:06:47 2019-07-19 06:59:48
6 2019-07-19 07:09:19 2019-07-19 07:07:17

实际增量仅是:

>>> print(result['end_time'] - result['start_time'])
0   00:02:13
1   00:01:08
2   00:02:35
3   00:01:01
4   00:01:52
5   00:06:59
6   00:02:02