如何合并两个没有共享列的数据框,其中一个包含日期范围,另一个包含日期?

1 投票
1 回答
41 浏览
提问于 2025-04-11 23:11

我有两个数据框(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

撰写回答