基于Pandas的时间戳事件5天内交叉匹配需求咨询
解决Pandas DataFrame时间范围内交叉匹配的问题
这需求挺典型的,我们可以通过Pandas的时间处理和广播运算来高效实现,一步步来:
步骤1:转换日期为Timestamp类型
首先得把原始的字符串日期转换成Pandas能识别的Timestamp类型,这样才能进行时间差计算:
import pandas as pd df1 = pd.DataFrame({'date_1': ['2016-10-10', '2016-10-11', '2016-10-18', '2016-10-29']}) df2 = pd.DataFrame({'date_2': ['2016-10-10', '2016-10-05', '2016-10-27', '2016-10-01']}) # 转换为Timestamp类型,启用时间计算能力 df1['date_1'] = pd.to_datetime(df1['date_1']) df2['date_2'] = pd.to_datetime(df2['date_2'])
步骤2:批量计算日期对的时间差并筛选
利用Pandas的广播特性,一次性计算df2每个日期与df1所有日期的天数差,再筛选出绝对值≤5的记录:
# 计算所有日期对的天数差:df2日期 - df1日期,转换为整数天数 delta_days = (df2['date_2'].values[:, None] - df1['date_1'].values).astype('timedelta64[D]').astype(int) # 取绝对值用于判断是否在5天范围内 delta_days_abs = abs(delta_days) # 生成布尔掩码,标记哪些日期对符合5天范围条件 mask = delta_days_abs <= 5
步骤3:生成匹配的索引和差值列表
遍历df2的每一行,提取对应的df1索引和天数差:
matched_indices = [] matched_deltas = [] for i in range(len(df2)): # 获取当前df2行符合条件的df1索引 valid_idx = df1.index[mask[i]].tolist() matched_indices.append(valid_idx) # 获取对应的天数差(和示例一致取绝对值后的数值) valid_deltas = delta_days_abs[i][mask[i]].tolist() matched_deltas.append(valid_deltas)
验证结果
运行完代码后,输出完全符合预期:
print(matched_indices) # [[0, 1], [0], [3], []] print(matched_deltas) # [[0, 1], [5], [2], []]
补充说明
- 广播运算比逐行循环查找高效得多,数据量越大优势越明显;
- 如果你的数据集规模特别大,可以尝试
pd.merge_asof做更优化的匹配,但上面的方法对于常规数据已经足够简单直观。
内容的提问来源于stack exchange,提问作者fen
相关产品推荐
相关产品推荐

