使用Pandas生成CSV时陷入无限循环问题求助
问题分析与修复方案
核心问题
你的代码出现无限循环、数据爆炸的原因主要有三点:
- 嵌套循环的终止逻辑漏洞:内层循环的
break仅跳出当前array_osp的遍历,但外层循环会持续遍历array_sig的每一行;若buscarID函数逻辑有误,会导致每一行sig反复触发行添加操作,最终生成海量数据。 - 低效的DataFrame拼接:每次循环调用
pd.concat拼接小DataFrame,不仅性能极差,一旦循环失控会快速耗尽内存,直接导致编辑器崩溃。 buscarID函数可能存在逻辑错误:如果该函数无法正确判断值是否存在,会导致分支被无限触发,不断重复添加行。
具体修复步骤
1. 抛弃嵌套iterrows()循环,改用Pandas矢量化操作
Pandas的核心优势是矢量化运算,手动双层循环既低效又容易出错。要实现「CSV A某行的值存在于CSV B任意行中」的需求,直接用isin()方法即可:
# 假设匹配的目标列是'valor',根据实际业务修改列名 matched_mask = array_sig['valor'].isin(array_osp['valor']) matched_data = array_sig[matched_mask]
2. 用列表收集数据,最后一次性生成DataFrame
避免频繁拼接DataFrame,先把需要添加的行数据存入列表,循环结束后统一转换为DataFrame:
data_list = [] pivote = 1 # 初始化ID计数器 for i, sig in array_sig.iterrows(): # 直接用isin替代buscarID函数,避免自定义函数的逻辑错误 valor_sig = sig['目标列'] # 替换为实际列名 buscarIDOSP = valor_sig in array_osp['目标列'].values if not buscarIDOSP: # 按valorReemplazo的逻辑构造字典,添加到列表 data_list.append({ "FTTH": ftth_osp, "ID": pivote, # 其他字段根据实际需求补充 }) else: data_list.append({ "FTTH": ftth_osp, "ID": pivote }) pivote += 1 # 最后一次性生成DataFrame dataLoader = pd.DataFrame(data_list)
3. 修正循环终止逻辑
如果每个sig只需要处理一次,在内层循环找到匹配项后,可以设置标志位控制外层循环的执行:
for i, sig in array_sig.iterrows(): processed = False for j, osp in array_osp.iterrows(): if ...: # 原有的if/elif逻辑 ... else: buscarIDOSP = valor_sig in array_osp['目标列'].values if not buscarIDOSP: data_list.append(...) processed = True break else: data_list.append(...) pivote +=1 processed = True break # 如果当前sig已处理,直接进入下一轮外层循环 if processed: continue
4. 检查并替换buscarID函数
自定义函数容易引入逻辑错误,直接用Pandas的内置方法替代:
# 替换buscarID(valor_sig, array_osp)为: def buscarID(valor_sig, array_osp, target_col): return valor_sig in array_osp[target_col].values
完整重构示例
假设你的需求是筛选array_sig中存在于array_osp的行,并生成带ID和FTTH字段的输出CSV:
import pandas as pd def process_csvs(input_sig, input_osp, output_path): # 读取输入CSV array_sig = pd.read_csv(input_sig) array_osp = pd.read_csv(input_osp) # 定义匹配列(根据实际业务修改) match_col = "valor" # 筛选符合条件的行 matched_data = array_sig[array_sig[match_col].isin(array_osp[match_col])] # 添加ID和FTTH字段 matched_data["ID"] = range(1, len(matched_data) + 1) matched_data["FTTH"] = "FTTH_VALUE" # 替换为实际业务值 # 保存输出CSV matched_data.to_csv(output_path, index=False) # 调用函数 process_csvs("sig.csv", "osp.csv", "output.csv")
内容的提问来源于stack exchange,提问作者Mauricio A
相关产品推荐
相关产品推荐

