Python中for循环创建多个DataFrame失败,求代码修正方案
问题描述
遍历ENTREGAS_G1列表中的日期字符串,读取对应路径下的DBF文件并转换为DataFrame,合并后创建以PROFECO_+日期命名的多个DataFrame(如PROFECO_19052022等),但代码无法正常运行,需改进。
原代码
ENTREGAS_G1=['19052022','27052022', '02062022','06062022','13062022','20062022','27062022', '05072022','11072022','20072022','26072022', '01082022'] for i in range(len(ENTREGAS_G1)): print('INFORMACION_'+ENTREGAS_G1[i]) lista_date = folder_listas+'/SOLICITUD_INFORMACION_'+ENTREGAS_G1[i] esta = DBF(os.path.join(lista_date,'SOLICITUD_INFORMACION_'+ENTREGAS_G1[i]+'_ESTABLECIMIENTOS.DBF')) DF_ESTA=pd.DataFrame(iter(esta)) prec = DBF(os.path.join(lista_date,'SOLICITUD_INFORMACION_'+ENTREGAS_G1[i]+'_PRECIOS.DBF')) DF_PREC=pd.DataFrame(iter(prec)) prod = DBF(os.path.join(lista_date,'SOLICITUD_INFORMACION_'+ENTREGAS_G1[i]+'_PRODUCTOS.DBF')) DF_PROD=pd.DataFrame(iter(prod)) MERGE1 = pd.merge(DF_PREC, DF_PROD, on=['CVE_PRODUC','CVE_MARCA']) MERGE2 = pd.merge(DF_ESTA, MERGE1, on='FOLIO') globals()[PROFECO_+i] = MERGE2.assign(identrega=ENTREGAS_G1[i]) print('Done:','PROFECO_'+ENTREGAS_G1[i])
代码问题分析
- 变量拼接错误:
PROFECO_不是字符串,直接拼接会触发语法错误;i是整数索引,不能直接和字符串拼接,需用对应日期字符串生成变量名。 - 循环逻辑冗余:遍历列表元素比遍历索引更简洁,可避免索引操作失误。
- 无异常处理:读取DBF文件、合并DataFrame时可能出现路径错误、文件缺失、列名不匹配等问题,缺少容错机制会导致程序直接崩溃。
- 全局变量滥用:用
globals()动态创建全局变量会污染命名空间,不利于后续维护和管理。
改进后的代码
import pandas as pd import os from dbfread import DBF # 需先安装库:pip install dbfread ENTREGAS_G1=['19052022','27052022', '02062022','06062022','13062022','20062022','27062022', '05072022','11072022','20072022','26072022', '01082022'] # 用字典存储生成的DataFrame,替代动态全局变量,更易管理 profeco_dfs = {} # 直接遍历日期字符串,简化循环逻辑 for date_str in ENTREGAS_G1: print(f'INFORMACION_{date_str}') # 用f-string简化路径拼接,提升可读性 lista_date = f'{folder_listas}/SOLICITUD_INFORMACION_{date_str}' try: # 读取DBF文件并转为DataFrame esta_path = os.path.join(lista_date, f'SOLICITUD_INFORMACION_{date_str}_ESTABLECIMIENTOS.DBF') DF_ESTA = pd.DataFrame(DBF(esta_path)) prec_path = os.path.join(lista_date, f'SOLICITUD_INFORMACION_{date_str}_PRECIOS.DBF') DF_PREC = pd.DataFrame(DBF(prec_path)) prod_path = os.path.join(lista_date, f'SOLICITUD_INFORMACION_{date_str}_PRODUCTOS.DBF') DF_PROD = pd.DataFrame(DBF(prod_path)) # 明确合并方式(可根据需求改为left/outer/right) MERGE1 = pd.merge(DF_PREC, DF_PROD, on=['CVE_PRODUC','CVE_MARCA'], how='inner') MERGE2 = pd.merge(DF_ESTA, MERGE1, on='FOLIO', how='inner') # 添加交付日期标识并存入字典 profeco_df = MERGE2.assign(identrega=date_str) profeco_dfs[f'PROFECO_{date_str}'] = profeco_df # 若确实需要全局变量(不推荐),可保留以下代码 # globals()[f'PROFECO_{date_str}'] = profeco_df print(f'Done: PROFECO_{date_str}') except FileNotFoundError: print(f'错误:未找到日期{date_str}对应的DBF文件') except KeyError as e: print(f'错误:合并时缺少列{e}') except Exception as e: print(f'处理日期{date_str}时出错:{str(e)}')
关键改进点
- 用f-string简化拼接:减少字符串拼接错误,提升代码可读性。
- 字典存储DataFrame:避免全局变量污染,方便后续批量操作(如遍历所有生成的DataFrame)。
- 添加异常捕获:处理文件缺失、列名不匹配等常见错误,保证程序稳定性。
- 简化循环逻辑:直接遍历列表元素,避免索引操作失误。
- 明确合并规则:指定
how参数,让合并逻辑更清晰,避免隐式行为导致的问题。
内容的提问来源于stack exchange,提问作者Alexis Rodas
相关产品推荐
相关产品推荐

