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

使用while循环进行Pandas DataFrame匹配时陷入无限循环求助

解决DataFrame嵌套循环引发的无限循环问题

首先,咱们来拆解你遇到的问题:你的代码运行后只打印了0 0就陷入无限循环,核心原因是多余的while循环内部没有更新变量j,导致条件永远成立。我先帮你分析问题,再给出修复和优化的方案。

问题代码回顾

你原本的代码整理后如下:

import pandas as pd

for i in range(len(a1)): 
    title_derived = [] 
    k = 100000 
    print(i) 
    for j in range(len(b1)): 
        print(j) 
        while j < (k + 6): 
            # print(b1.iloc[i][10], a1.iloc[j][3]) 
            if b1.iloc[j][10] == a1.iloc[i][3]: 
                print(j,k) 
                print('1st if ' + str(j)) 
                print (b1.iloc[j][1], a1.iloc[i][11], b1.iloc[j][5]) 
                if (((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][11]) <= pd.to_datetime(b1.iloc[j][5]))) or ((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][8]) <= pd.to_datetime(b1.iloc[j][5])))) : 
                    print('2nd if' + str(j)) 
                    title_derived.append(b1.iloc[j][15]) 
                    print('inserted ' + b1.iloc[j][15] + ' in ' + str(i) + ' th record ') 
        a1.iat[i,65] = title_derived 

无限循环的根源

看这段代码里的while j < (k + 6):

  • k被硬编码为100000,条件等价于j < 100006
  • 当j从for循环的0开始时,进入while循环后没有任何代码修改j的值,j永远是0,满足0 < 100006的条件,导致循环永远无法退出。
  • 这个while循环完全是多余的——你的逻辑是遍历b1的每一行,不需要额外的范围限制。

修复方案:去掉多余的while循环

先给你修复基础的循环代码,解决无限循环问题,同时优化重复的日期转换操作(避免每次循环都调用pd.to_datetime,提升效率):

import pandas as pd

# 提前预处理日期列,避免循环内重复转换,大幅提升效率
b1['start_date'] = pd.to_datetime(b1.iloc[:, 1])
b1['end_date'] = pd.to_datetime(b1.iloc[:, 5])
a1['target_date1'] = pd.to_datetime(a1.iloc[:, 11])
a1['target_date2'] = pd.to_datetime(a1.iloc[:, 8])

for i in range(len(a1)):
    title_derived = []
    print(f"Processing a1 row {i}")
    # 提前取出当前a1行的关键值,减少重复索引
    a_match_val = a1.iloc[i, 3]
    a_date1 = a1.loc[i, 'target_date1']
    a_date2 = a1.loc[i, 'target_date2']
    
    for j in range(len(b1)):
        print(f"Checking b1 row {j}")
        # 第一个匹配条件:b1第11列(iloc[j,10])等于a1第4列(iloc[i,3])
        if b1.iloc[j, 10] == a_match_val:
            print(f"Matched value at b1 row {j}")
            b_start = b1.loc[j, 'start_date']
            b_end = b1.loc[j, 'end_date']
            # 第二个日期区间条件
            if (b_start <= a_date1 <= b_end) or (b_start <= a_date2 <= b_end):
                print(f"Date condition satisfied at b1 row {j}")
                matched_title = b1.iloc[j, 15]
                title_derived.append(matched_title)
                print(f"Added '{matched_title}' to a1 row {i}")
    # 将结果赋值到a1的第66列(索引65)
    a1.iat[i, 65] = title_derived

更高效的优化:用Pandas向量操作替代嵌套循环

上面的循环代码虽然能解决问题,但对于大尺寸的DataFrame来说效率极低——Pandas的核心优势是向量化操作,避免逐行遍历。这里给你推荐更高效的实现方式:

import pandas as pd

# 预处理日期列
b1['start_date'] = pd.to_datetime(b1.iloc[:, 1])
b1['end_date'] = pd.to_datetime(b1.iloc[:, 5])
a1['target_date1'] = pd.to_datetime(a1.iloc[:, 11])
a1['target_date2'] = pd.to_datetime(a1.iloc[:, 8])

# 定义函数:对a1的每一行,找到b1中满足条件的标题
def get_matching_titles(row):
    # 构建筛选条件
    mask = (b1.iloc[:, 10] == row.iloc[3]) & \
           ((b1['start_date'] <= row['target_date1']) & (row['target_date1'] <= b1['end_date']) | \
            (b1['start_date'] <= row['target_date2']) & (row['target_date2'] <= b1['end_date']))
    # 返回匹配的标题列表
    return b1.loc[mask, b1.columns[15]].tolist()

# 应用函数到a1的每一行,赋值到目标列
a1.iloc[:, 65] = a1.apply(get_matching_titles, axis=1)

这个方法利用apply和布尔索引,比嵌套循环快得多,代码也更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:29:42