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

Python优化DataFrame嵌套循环及解决数据分片报错问题

问题与解决方案

问题说明

  1. 执行以下嵌套for循环时出现无限循环:
for i in df2.index: 
    for j in df1.F_Date:
        A0=df2['X'][i]
        A1=df2['Y'][i]
        A1=df2['Z'][i]  # 笔误:覆盖了A1的值
        df1.loc[(df1['ID'] == A0) & (df1['F_Date'] ==j ), 'Rule'] = 'A0 Occuar'
        df1.loc[(df1['ID'] == A1) & (df1['F_Date'] ==j ), 'Rule'] = 'A1 Occuar'
        df1.loc[(df1['ID'] == A2) & (df1['F_Date'] ==j ), 'Rule'] = 'A2 Occuar'  # A2未定义,会报错
  1. 使用np.array_split拆分df1后执行for j in split_df.F_Date:报错:AttributeError: 'list' object has no attribute 'F_Date'
  2. 实际需求:遍历df1的每个日期和df2的每一行,检查X、Y、Z是否在该日期出现,若出现则计算X、Y的最大Clear_Date与Z的Clear_Date的时间差,输出对应结果

示例数据

df1:

IDF_DateClear_Date
AB2023-10-012023-10-02
CD2023-10-022023-10-03
EF2023-10-022023-10-04

df2:

XYZ
ABCDEF
CDABEF
EFABCD

预期输出

XYZTime_Difference
ABCDEF25:00
CDABEF28:00
EFABCD02:30

问题原因分析

  1. 嵌套循环问题:
    • 代码存在笔误:A1=df2['Z'][i]覆盖了Y列的值,且A2未定义,执行会直接报错
    • 遍历df1.F_Date会重复遍历所有日期行(包括重复日期),数据量大时会导致程序长时间运行,被误认为无限循环
    • 循环中频繁修改df1,效率极低,且可能引发索引异常
  2. 拆分df1报错问题:
    • np.array_split(df1, 20)返回的是由20个子DataFrame组成的列表,不是单个DataFrame,因此无法直接通过split_df.F_Date访问列,需遍历列表中的每个子DataFrame

解决方案

使用Pandas字典映射替代嵌套循环,提升效率并避免异常:

代码实现

import pandas as pd

# 构造示例数据(实际使用时替换为你的真实数据)
df1 = pd.DataFrame({
    'ID': ['AB', 'CD', 'EF'],
    'F_Date': ['2023-10-01', '2023-10-02', '2023-10-02'],
    'Clear_Date': ['2023-10-02', '2023-10-03', '2023-10-04']
})
# 转换日期列为datetime类型,方便计算时间差
df1['F_Date'] = pd.to_datetime(df1['F_Date'])
df1['Clear_Date'] = pd.to_datetime(df1['Clear_Date'])

df2 = pd.DataFrame({
    'X': ['AB', 'CD', 'EF'],
    'Y': ['CD', 'AB', 'AB'],
    'Z': ['EF', 'EF', 'CD']
})

# 构建(F_Date, ID)到Clear_Date的映射字典,快速查找
date_id_clear_map = df1.set_index(['F_Date', 'ID'])['Clear_Date'].to_dict()

results = []
# 遍历df2的每一行
for _, row in df2.iterrows():
    x, y, z = row['X'], row['Y'], row['Z']
    # 遍历df1中的所有唯一日期
    for date in df1['F_Date'].unique():
        # 检查X、Y、Z在当前日期是否都存在
        if (date, x) in date_id_clear_map and (date, y) in date_id_clear_map and (date, z) in date_id_clear_map:
            # 获取对应的Clear_Date
            x_clear = date_id_clear_map[(date, x)]
            y_clear = date_id_clear_map[(date, y)]
            z_clear = date_id_clear_map[(date, z)]
            # 计算X、Y的最大时间与Z的时间差
            max_xy_clear = max(x_clear, y_clear)
            time_diff = max_xy_clear - z_clear
            # 转换为"小时:分钟"格式
            total_hours = time_diff.days * 24 + time_diff.seconds // 3600
            total_minutes = (time_diff.seconds % 3600) // 60
            time_diff_str = f"{total_hours:02d}:{total_minutes:02d}"
            # 将结果加入列表
            results.append({
                'X': x,
                'Y': y,
                'Z': z,
                'Time_Difference': time_diff_str
            })

# 转换为结果DataFrame
result_df = pd.DataFrame(results)
print(result_df)

代码说明

  • 用字典映射替代循环查找,大幅提升效率
  • 遍历唯一日期而非所有日期行,避免重复计算
  • 避免在循环中修改原DataFrame,减少异常风险
  • 时间差计算逻辑清晰,格式化为需求的"小时:分钟"样式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:27:05