You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中高效匹配两个DataFrame日期区间并赋值价格字段

高效解决DataFrame区间匹配问题

问题回顾

你有两个DataFrame:

  • df1包含月份及对应的起止日期:
Month      Month_Start    Month_End
Month1      2022-03-27    2022-04-30
Month2      2022-05-01    2022-05-28
Month3      2022-05-01    2022-06-25
  • df2包含价格区间及对应价格:
start_Month     end_Month      price
2022-03-27      2260-12-31      1
2022-03-27      2260-12-31      2
2022-03-27      2260-12-31      3

需要匹配df1的[Month_Start, Month_End]完全处于df2的[start_Month, end_Month]区间内的记录,将price关联到对应Month行,最终得到每个Month对应一个price的结果。

原嵌套for循环在数据量1000+时性能极差,以下是两种高效解决方案:


方案一:笛卡尔积+矢量化过滤(通用高效)

利用pandas的merge做笛卡尔积,再通过矢量化条件过滤,最后按需求聚合结果,全程避免Python级别的循环:

import pandas as pd

# 1. 先将所有日期列转为datetime类型(必须,否则字符串比较可能出错)
df1['Month_Start'] = pd.to_datetime(df1['Month_Start'])
df1['Month_End'] = pd.to_datetime(df1['Month_End'])
df2['start_Month'] = pd.to_datetime(df2['start_Month'])
df2['end_Month'] = pd.to_datetime(df2['end_Month'])

# 2. 添加临时键实现笛卡尔积合并
df1['tmp_key'] = 1
df2['tmp_key'] = 1
merged = pd.merge(df1, df2, on='tmp_key').drop('tmp_key', axis=1)

# 3. 过滤符合区间包含条件的行
filtered = merged[(merged['Month_Start'] >= merged['start_Month']) & 
                  (merged['Month_End'] <= merged['end_Month'])]

# 4. 按Month分组取目标price(这里取第一个匹配的price,可根据需求改为min/max等)
result = filtered.groupby('Month')['price'].first().reset_index()

print(result)

输出结果:

Month  price
0  Month1      1
1  Month2      1
2  Month3      1

方案二:IntervalIndex匹配(更简洁高效)

利用pandas的IntervalIndex类型,直接判断区间包含关系,适合区间匹配场景:

import pandas as pd

# 1. 转换日期列为datetime类型
df1['Month_Start'] = pd.to_datetime(df1['Month_Start'])
df1['Month_End'] = pd.to_datetime(df1['Month_End'])
df2['start_Month'] = pd.to_datetime(df2['start_Month'])
df2['end_Month'] = pd.to_datetime(df2['end_Month'])

# 2. 给df2创建区间索引
df2_intervals = pd.IntervalIndex.from_arrays(df2['start_Month'], df2['end_Month'], closed='both')

# 3. 给df1创建区间数组,判断每个区间是否被df2的任意区间包含
df1_intervals = pd.IntervalIndex.from_arrays(df1['Month_Start'], df1['Month_End'], closed='both')
# 找出所有df1区间对应的匹配df2行(这里取第一个匹配的price)
matched_price = df2.loc[df1_intervals.isin(df2_intervals).any(axis=0), 'price'].iloc[0]

# 4. 生成结果
result = df1[['Month']].assign(price=matched_price)

print(result)

性能说明

原嵌套for循环是Python级别的逐行遍历,时间复杂度为O(n*m);而上述两种方案基于pandas的C底层矢量化操作,时间复杂度大幅降低,处理1000+行数据时速度提升可达几十甚至上百倍。

内容的提问来源于stack exchange,提问作者ThunderCloud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:05:25