python - 基于重叠时间间隔连接两个数据集
问题描述
我正在尝试根据重叠间隔“合并”两个 Dataframe,如下所示:
数据集 1
开始日期 | 结束日期 | 字段1 |
---|---|---|
2020-01-01 | 2020-06-30 | 一个 |
2020-07-01 | 2020-12-31 | 乙 |
数据集 2
开始日期 | 结束日期 | 字段2 |
---|---|---|
2020-01-01 | 2020-04-30 | D |
2020-05-01 | 2020-08-31 | 乙 |
2020-09-01 | 2020-12-31 | F |
组合数据集
开始日期 | 结束日期 | 字段1 | 字段2 |
---|---|---|---|
2020-01-01 | 2020-04-30 | 一个 | D |
2020-05-01 | 2020-06-30 | 一个 | 乙 |
2020-07-01 | 2020-08-31 | 乙 | 乙 |
2020-09-01 | 2020-12-31 | 乙 | F |
该示例的代码是python,如下所示
import pandas as pd
df1 = pd.DataFrame([['2020-01-01','2020-06-30','A'],
['2020-07-01','2020-12-31','B']],
columns = ['start_date', 'end_date', 'field1'])
df2 = pd.DataFrame([['2020-01-01','2020-04-30','D'],
['2020-05-01','2020-08-31','E'],
['2020-09-01','2020-12-31','F']],
columns = ['start_date', 'end_date', 'field2'])
expected_output = pd.DataFrame([['2020-01-01','2020-04-30','A','D'],
['2020-05-01','2020-06-30','A','E'],
['2020-07-01','2020-08-31','B','E'],
['2020-09-01','2020-12-31','B','F']],
columns = ['start_date', 'end_date','field1', 'field2'])
我真的试图想办法做到这一点,但我必须说我的页面是空白的......非常感谢您的任何推荐!
解决方案
您可以按以下步骤进行:
- 对于,通过对应于每行从 到 的期间来 定义每
df1
行的日期范围pd.date_range()
start_date
end_date
- 同样,对于
df2
以类似方式定义每一行的日期范围 - 将新创建的日期列表
date_range
分解为多行df1
,df2
每个日期在一行中。 df1
对每个数据帧中df2
的date_range
列执行内部合并。现在,我们已经可以获取每个原始数据帧中公共日期的交集,以进行进一步处理。- Group by
field1
并且field2
在交集日期上,我们可以start_date
通过获取组中的第一个条目来获取新的公共日期范围。 - 同样,我们可以
end_date
通过获取组中的最后一个条目来获取新的公共日期范围。 - 最后,我们聚合这些条目并只取每个组中已经包含我们想要的所有必需信息的第一行。
df1a = (df1.assign(date_range=df1.apply(lambda x: pd.date_range(start=x['start_date'], end=x['end_date']), axis=1))
.explode('date_range'))
df2a = (df2.assign(date_range=df2.apply(lambda x: pd.date_range(start=x['start_date'], end=x['end_date']), axis=1))
.explode('date_range'))
df3 = df1a.merge(df2a, on='date_range')
df3['start_date'] = df3.groupby(['field1', 'field2'])['date_range'].transform('first')
df3['end_date'] = df3.groupby(['field1', 'field2'])['date_range'].transform('last')
df4 = df3.groupby(['field1', 'field2']).agg('first').reset_index()[['start_date', 'end_date', 'field1', 'field2']]
print(df4)
start_date end_date field1 field2
0 2020-01-01 2020-04-30 A D
1 2020-05-01 2020-06-30 A E
2 2020-07-01 2020-08-31 B E
3 2020-09-01 2020-12-31 B F
推荐阅读
- python - 时间字符串的时差(只需要计算分钟的差异然后转换为秒)
- python - 使用 Warnsdorff 规则的 Knight 巡回赛给出了错误的输出,主要是奇数尺寸
- flutter - 隔离无法显示本地通知,并且应用程序终止后flutterisolate不会持续存在
- applescript - 是否可以初始化一个变量,然后使用 if 语句输出相同的变量?
- android - 如何将一个批次分成多个批次以在 Android 的 Firestore 中设置文档
- regex - 根据另一列中的文本更改单元格背景颜色
- cypress - 如何从赛普拉斯的列表项中选择特定项
- c - 如何正确打印 2.30 定点变量
- javascript - 从另一个页面导航到主页时,主页会略微向下移动
- reactjs - 为什么 onChange 上的 setState 不给出最大更新深度超出错误