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

如何用Pandas高效实现基于时间区间的DataFrame合并

高效实现基于时间区间的DataFrame合并

需求说明

需要合并两个DataFrame:

  • 第一个DataFrame(记为df1)包含time_1、time_2及其他列
  • 第二个DataFrame(记为df2)包含time_3及其他列(通常行数更多)

合并规则:当df2中time_3的取值处于df1某行的time_1与time_2区间内时,将df1的该行与df2的对应行合并,df1的行需根据匹配次数重复。

示例数据

df1格式:

time_1time_2dummy_data
2023-10-01 04:02:002023-10-01 08:29:00-245.669907
2023-10-01 04:03:002023-10-01 08:49:00-1772.948571
.........

df2格式:

time_3dummy_data2
2023-10-01 06:21:13.238024-131.367901
2023-10-01 06:47:19.796628-236.277444
2023-10-01 07:37:06.4387405.915493
2023-10-01 08:16:16.995256-134.032433
2023-10-01 08:33:53.081095-103.733212

预期合并结果:

time_1time_2dummy_datatime_3dummy_data2
2023-10-01 04:02:002023-10-01 08:29:00-245.6699072023-10-01 06:21:13.238024-131.367901
2023-10-01 04:02:002023-10-01 08:29:00-245.6699072023-10-01 06:47:19.796628-236.277444
2023-10-01 04:02:002023-10-01 08:29:00-245.6699072023-10-01 07:37:06.4387405.915493
2023-10-01 04:02:002023-10-01 08:29:00-245.6699072023-10-01 08:16:16.995256-134.032433
2023-10-01 04:03:002023-10-01 08:49:00-1772.9485712023-10-01 06:21:13.238024-131.367901
2023-10-01 04:03:002023-10-01 08:49:00-1772.9485712023-10-01 06:47:19.796628-236.277444
2023-10-01 04:03:002023-10-01 08:49:00-1772.9485712023-10-01 07:37:06.4387405.915493
2023-10-01 04:03:002023-10-01 08:49:00-1772.9485712023-10-01 08:16:16.995256-134.032433
2023-10-01 04:03:002023-10-01 08:49:00-1772.9485712023-10-01 08:33:53.081095-103.733212

低效原代码问题

原代码使用嵌套循环和append方法,每次append都会创建新的DataFrame,内存开销大且速度极慢,尤其在数据量较大时表现明显。

高效Pandas实现方案

利用Pandas的向量化操作实现交叉连接+条件过滤,性能远高于循环方案:

import pandas as pd

# 读取数据
df1 = pd.read_csv("datetime_list.csv")
df2 = pd.read_csv('dataframe.csv')

# 转换所有时间列为datetime类型(必须步骤,否则无法进行时间比较)
df1['time_1'] = pd.to_datetime(df1['time_1'])
df1['time_2'] = pd.to_datetime(df1['time_2'])
df2['time_3'] = pd.to_datetime(df2['time_3'])

# 添加临时键实现交叉连接
df1['temp_key'] = 1
df2['temp_key'] = 1

# 交叉连接后过滤符合时间区间的行,最后删除临时键
merged_df = pd.merge(df1, df2, on='temp_key') \
              .query('time_3 >= time_1 and time_3 < time_2') \
              .drop('temp_key', axis=1)

# 调整列顺序以匹配预期结果(可选)
merged_df = merged_df[['time_1', 'time_2', 'dummy_data', 'time_3', 'dummy_data2']]

方案说明

  1. 时间类型转换:确保所有时间列是datetime64类型,才能正确进行区间比较。
  2. 交叉连接:通过添加临时相同键实现两个DataFrame的全量匹配,这一步是向量化操作,效率远高于循环。
  3. 条件过滤:用query方法快速筛选出time_3落在[time_1, time_2)区间内的行,同样是向量化操作,性能优异。
  4. 清理临时列:删除用于交叉连接的临时键,得到最终结果。

性能优化补充

如果数据量极大(如百万级行),交叉连接可能占用较多内存,可以改用numpy广播来生成匹配索引,进一步降低内存开销:

import numpy as np

# 转换时间列为数值类型(timestamp)以加速比较
t1 = df1['time_1'].values.astype(np.int64)
t2 = df1['time_2'].values.astype(np.int64)
t3 = df2['time_3'].values.astype(np.int64)

# 广播生成匹配矩阵
mask = (t3[:, None] >= t1) & (t3[:, None] < t2)

# 获取匹配的索引对
df1_idx, df2_idx = np.where(mask)

# 合并结果
merged_df = pd.concat([
    df1.iloc[df1_idx].reset_index(drop=True),
    df2.iloc[df2_idx].reset_index(drop=True)
], axis=1)

这种方法直接通过numpy的广播生成布尔矩阵,再提取匹配索引,内存占用更低,速度更快。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:22:05