修复DataFrame行数与TGT_INSRT_CT列比对的真值歧义报错
修复S3 CSV行数匹配验证的代码错误
错误原因
报错ValueError: The truth value of a DataFrame is ambiguous是因为代码中if df_filtered == numlines:这一行直接将DataFrame对象与单个数值做比较,Pandas无法确定整个DataFrame的布尔判定逻辑,导致歧义错误。
另外原代码存在性能问题:循环内重复读取LOAD_STAT.csv,会多次发起S3请求,降低运行效率。
修复方案
- 将
LOAD_STAT.csv的读取逻辑移到循环外部,只执行一次读取操作 - 提前构建表名到统计值的映射字典,方便快速查找对应表的记录数
- 针对每个目标CSV文件,提取单个统计数值后再与文件行数做比较,避免DataFrame和数值直接对比
修复后的代码
import boto3 import pandas as pd s3 = boto3.resource('s3') my_bucket = s3.Bucket('bucket-name') prefix_df = ['ADR2','ADR6','ADRC','ADRU','BUT000','BUT020','BUT021_FS','BUT050','BUT0ID','BUT100'] def get_rowcount_csv(): # 仅读取一次LOAD_STAT.csv,减少S3请求次数 df_midas = pd.read_csv(f's3://path/to/file/LOAD_STAT.csv', sep='|', usecols=['TGT_INSRT_CT', 'TGT_TBL_NM']) # 构建表名到插入记录数的映射字典 stat_map = df_midas[df_midas['TGT_TBL_NM'].isin(prefix_df)].set_index('TGT_TBL_NM')['TGT_INSRT_CT'].to_dict() for my_bucket_object in my_bucket.objects.filter(Prefix='decrypted/'): if my_bucket_object.key.endswith('.csv'): filename = my_bucket_object.key.split('/')[-1] table_name = filename.split('.')[0] if table_name in prefix_df: # 读取当前CSV并统计行数 df = pd.read_csv(f's3://path/to/file/{filename}', sep='|') num_lines = len(df) print(f'{filename}: {num_lines}') # 获取对应表的预期记录数 expected_count = stat_map.get(table_name) if expected_count is not None: if num_lines == expected_count: print(f"匹配成功:{filename} 行数与LOAD_STAT记录一致") else: print(f"匹配失败:{filename} 行数{num_lines},LOAD_STAT记录{expected_count}") else: print(f"警告:{table_name} 在LOAD_STAT.csv中无对应记录") get_rowcount_csv()
关键改进点
- 优化IO操作,避免循环内重复读取S3文件
- 通过字典映射实现快速查找,提升匹配效率
- 增加异常场景提示,增强代码健壮性
内容的提问来源于stack exchange,提问作者Lilcodemuffin
相关产品推荐
相关产品推荐

