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

Python处理Excel日期匹配代码运行缓慢且结果不符预期求助

Pandas处理Excel日期范围匹配:效率优化与结果修正

问题描述

现有两个Excel表格:

  • coilid(约3000行):需用每行的DT_START日期匹配范围
  • retifica:用Data de entrada(入厂日期)和Data de Saída(出厂日期)作为匹配范围

需求:

  • 若DT_START落在retifica的日期范围内,导出该行coilid数据 + retifica的ret、cilindro单元格
  • 若不匹配,仅导出coilid行

原代码运行耗时极长,且结果不符合预期,代码如下:

import pandas as pd

retifica = pd.read_excel('C:\\Arquivoparamim.xlsx', sheet_name='Planilha1')
retifica = retifica.sort_values(by=['Data Retífica'], ascending=True)

coilid = pd.read_excel('C:\\Arquivoparamim.xlsx', sheet_name='Planilha2')
coilid = coilid.sort_values(by=['DT_START'], ascending=True)

match=pd.DataFrame()

for x in range (coilid.shape[0]):
    for y in range (retifica.shape[0]):
        if (coilid.iloc[x,2]>retifica.iloc[y,16])&(coilid.iloc[x,2]<retifica.iloc[y,18]):
            matchaux = [coilid.iloc[x],retifica.iloc[y]]
        else:
            matchaux = [coilid.iloc[x]]
            match=match.append(matchaux)
        break
    

match.to_excel('Libraries\\Pictures\\aline.xlsx')

原代码核心问题

  1. 双重循环效率极低:3000行coilid × 3000行retifica = 900万次迭代,属于O(n*m)复杂度,完全违背Pandas向量化操作的设计逻辑
  2. df.append()性能灾难:循环中反复调用append会不断创建新的DataFrame,内存开销大且速度极慢
  3. 逻辑错误:内层循环的break仅检查retifica的第一行,未遍历所有可能的匹配项;else分支的append位置错误,导致结果重复或缺失
  4. 日期类型未校验:若Excel读取的日期是字符串格式,直接比较会出现逻辑错误(字符串比较≠日期比较)

优化解决方案

利用Pandas的merge_asof(适合排序后的时间范围匹配),实现O(n+m)线性复杂度的高效匹配,同时修正逻辑:

修正后代码

import pandas as pd

# 读取数据
retifica = pd.read_excel('C:\\Arquivoparamim.xlsx', sheet_name='Planilha1')
coilid = pd.read_excel('C:\\Arquivoparamim.xlsx', sheet_name='Planilha2')

# 1. 转换日期列为datetime类型(关键:避免字符串比较错误)
retifica['Data de entrada'] = pd.to_datetime(retifica['Data de entrada'])
retifica['Data de Saída'] = pd.to_datetime(retifica['Data de Saída'])
coilid['DT_START'] = pd.to_datetime(coilid['DT_START'])

# 2. 按匹配日期排序(merge_asof要求必须排序)
retifica = retifica.sort_values('Data de entrada')
coilid = coilid.sort_values('DT_START')

# 3. 用merge_asof做左连接,匹配DT_START >= Data de entrada的最近记录
# 仅保留需要的ret、cilindro列,减少数据量
match = pd.merge_asof(
    coilid,
    retifica[['Data de entrada', 'Data de Saída', 'ret', 'cilindro']],
    left_on='DT_START',
    right_on='Data de entrada',
    direction='backward'  # 找DT_START之前最近的Data de entrada
)

# 4. 过滤出DT_START在[Data de entrada, Data de Saída)范围内的行
# 不匹配的行ret、cilindro会自动为NaN,保留原coilid数据
match = match[(match['DT_START'] < match['Data de Saída']) | match['Data de Saída'].isna()]

# 5. 清理不需要的中间列
match = match.drop(['Data de entrada', 'Data de Saída'], axis=1)

# 6. 导出结果
match.to_excel('Libraries\\Pictures\\aline.xlsx', index=False)

代码说明

  • 日期类型转换:确保所有日期列是datetime64类型,保证比较逻辑正确
  • merge_asof高效匹配:利用排序后的线性扫描,避免双重循环,速度提升数十倍
  • 精准过滤:仅保留DT_START落在日期范围内的匹配项,未匹配的行自动保留原coilid数据(ret、cilindro为NaN)
  • 减少冗余数据:仅合并需要的ret、cilindro列,降低内存占用

内容的提问来源于stack exchange,提问作者Aline De Souza Silva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:20:43