- 首先在您的数据框中创建一个带有
pd.date_range 的as_of_date 列,该列是带有lambda x: 的每行的开始日期和结束日期之间的日期列表(删除重复项并保留最后一个)。
- 分解
as_of_date 上的数据框,以准备合并date 和port。
- 只需合并数据框(根据您的第二个问题,您可以简单地排除此步骤)。
第 1 步:创建日期范围列
df['as_of_date'] = df.apply(lambda x: list(pd.date_range(x['start_date'], x['end_date'], freq='d')), axis=1)
df
Out[1]:
port currency start_date end_date \
0 PortA USD 2020-01-01 2020-01-04
1 PortA CAD 2020-01-04 2020-01-06
2 PortA EUR 2020-01-06 2020-01-11
3 PortA USD 2020-01-11 2020-01-15
as_of_date
0 [2020-01-01 00:00:00, 2020-01-02 00:00:00, 202...
1 [2020-01-04 00:00:00, 2020-01-05 00:00:00, 202...
2 [2020-01-06 00:00:00, 2020-01-07 00:00:00, 202...
3 [2020-01-11 00:00:00, 2020-01-12 00:00:00, 202...
第 2 步:分解数据框并删除重复项
df = df.explode('as_of_date').drop_duplicates('as_of_date', keep='last')
df
Out[2]:
port currency start_date end_date as_of_date
0 PortA USD 2020-01-01 2020-01-04 2020-01-01
0 PortA USD 2020-01-01 2020-01-04 2020-01-02
0 PortA USD 2020-01-01 2020-01-04 2020-01-03
1 PortA CAD 2020-01-04 2020-01-06 2020-01-04
1 PortA CAD 2020-01-04 2020-01-06 2020-01-05
2 PortA EUR 2020-01-06 2020-01-11 2020-01-06
2 PortA EUR 2020-01-06 2020-01-11 2020-01-07
2 PortA EUR 2020-01-06 2020-01-11 2020-01-08
2 PortA EUR 2020-01-06 2020-01-11 2020-01-09
2 PortA EUR 2020-01-06 2020-01-11 2020-01-10
3 PortA USD 2020-01-11 2020-01-15 2020-01-11
3 PortA USD 2020-01-11 2020-01-15 2020-01-12
3 PortA USD 2020-01-11 2020-01-15 2020-01-13
3 PortA USD 2020-01-11 2020-01-15 2020-01-14
3 PortA USD 2020-01-11 2020-01-15 2020-01-15
第 3 步:合并两个数据框(根据您的第二个问题 - 如果您没有 tbl 数据框,则可以忽略此步骤。而只需运行 df = df[['port', 'as_of_date', 'currency']] 以保留并重新排序您需要的列:
df_merge = pd.merge(df[['port', 'currency', 'as_of_date']], tbl, how='left', on=['as_of_date', 'port'])
df_merge
Out[3]:
port currency as_of_date
0 PortA USD 2020-01-01
1 PortA USD 2020-01-02
2 PortA USD 2020-01-03
3 PortA CAD 2020-01-04
4 PortA CAD 2020-01-05
5 PortA EUR 2020-01-06
6 PortA EUR 2020-01-07
7 PortA EUR 2020-01-08
8 PortA EUR 2020-01-09
9 PortA EUR 2020-01-10
10 PortA USD 2020-01-11
11 PortA USD 2020-01-12
12 PortA USD 2020-01-13
13 PortA USD 2020-01-14
14 PortA USD 2020-01-15
完整代码:
df = pd.DataFrame(data={
'port': ['PortA','PortA','PortA','PortA'],
'currency': ['USD', 'CAD', 'EUR', 'USD'],
'start_date': ['01/01/2020', '01/04/2020', '01/06/2020', '01/11/2020'],
'end_date': ['01/04/2020', '01/06/2020', '01/11/2020', '01/15/2020']
})
df[['start_date', 'end_date']] = df[['start_date', 'end_date']].apply(pd.to_datetime, errors='ignore')
tbl = pd.DataFrame(data={
'port': 'PortA',
'as_of_date': [x for x in pd.date_range(start='01/01/2020', end='01/15/2020')]
})
df['as_of_date'] = df.apply(lambda x: list(pd.date_range(x['start_date'], x['end_date'], freq='d')), axis=1)
df = df.explode('as_of_date').drop_duplicates('as_of_date', keep='last')
df_merge = pd.merge(df[['port', 'currency', 'as_of_date']], tbl, how='left', on=['as_of_date', 'port'])
df_merge