如何合并两个没有共享列的数据框,其中一个包含日期范围,另一个包含日期?
我有两个数据框(DataFrame):
import pandas as pd
df1 = pd.DataFrame(
{
'date': ['2024-01-01','2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05', '2024-01-06', '2024-01-07', '2024-01-08', '2024-01-09', '2024-01-10', '2024-01-11', '2024-01-12', '2024-01-13'],
'price': list(range(13))
}
)
df2 = pd.DataFrame(
{
'start': ['2024-01-01', '2024-01-03', '2024-01-10'],
'end': ['2024-01-03', '2024-01-08', '2024-01-12'],
'id': ['a', 'b', 'c']
}
)
这是我期望的输出结果。我想把 id
加到 df1
里:
date price id
0 2024-01-01 0 NaN
1 2024-01-02 1 a
2 2024-01-03 2 a
3 2024-01-04 3 b
4 2024-01-05 4 b
5 2024-01-06 5 b
6 2024-01-07 6 b
7 2024-01-08 7 b
8 2024-01-09 8 NaN
9 2024-01-10 9 NaN
10 2024-01-11 10 c
11 2024-01-12 11 c
12 2024-01-13 12 NaN
处理的过程是这样的。让我给你举个例子,看看输出的第 1
行:
a) 这个 date
是 2024-01-02。我们需要查找 df2
。每一行 df2
都有一个范围。这个 date
落在 df2
的第一行的范围内。注意,start
是不包括的,而 end
是包括的。
b) 从找到的 df2
行中获取 id
,然后放到输出结果里。
因为这两个数据框之间没有共同的列,所以我用了一个循环来得到输出结果。这个方法可以用,但我不确定这是不是最好的方法:
df1['date'] = pd.to_datetime(df1.date)
df2[['start', 'end']] = df2[['start', 'end']].apply(pd.to_datetime)
for idx, row in df2.iterrows():
start = row['start']
end = row['end']
id = row['id']
df1.loc[df1.date.between(start, end, inclusive='right'), 'id'] = id
有什么建议吗?
1 个回答
1
另外一个选择是使用 pd.cut
:
bins = pd.IntervalIndex.from_arrays(df2["start"], df2["end"])
df1["id"] = pd.cut(df1["date"], bins).map(dict(zip(bins, df2["id"])))
print(df1)
输出结果是:
date price id
0 2024-01-01 0 NaN
1 2024-01-02 1 a
2 2024-01-03 2 a
3 2024-01-04 3 b
4 2024-01-05 4 b
5 2024-01-06 5 b
6 2024-01-07 6 b
7 2024-01-08 7 b
8 2024-01-09 8 NaN
9 2024-01-10 9 NaN
10 2024-01-11 10 c
11 2024-01-12 11 c
12 2024-01-13 12 NaN