S3桶中精准筛选指定CSV文件读取的实现方法问询
解决方案:精准筛选S3桶中指定CSV文件并统计行数
问题根源
你之前用prefix_df匹配失败,核心原因是大小写不匹配:prefix_df里是小写字符串,但S3桶里的文件名是大写开头的(比如BPR2.csv),直接对比自然匹配不上。另外你代码里pd.read_csv的S3路径写死了固定值,应该根据桶名和文件实际路径动态生成,否则会导致文件找不到。
方案一:基于文件名前缀匹配(兼容大小写)
修改匹配逻辑,将文件名转为小写后和prefix_df对比,同时修正S3文件路径:
import boto3 import pandas as pd s3 = boto3.resource('s3') my_bucket = s3.Bucket('my-bucket-name') prefix_df = ['bpr2','bpr6','bprc','bpuu','tap000','tap020'] def get_rowcount_csv(): 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] # 提取文件名前缀(去掉.csv)并转小写,和prefix_df匹配 file_prefix = filename.replace('.csv', '').lower() if file_prefix in prefix_df: # 修正S3路径:使用实际桶名+文件完整key s3_path = f's3://my-bucket-name/{my_bucket_object.key}' df = pd.read_csv(s3_path, sep='|') numlines = len(df) print(f'{filename}: {numlines}') get_rowcount_csv()
方案二:直接指定目标文件名集合(更精准)
如果目标文件名固定,直接定义目标文件名的集合,判断当前文件是否在集合内,这种方式更直观且不会出错:
import boto3 import pandas as pd s3 = boto3.resource('s3') my_bucket = s3.Bucket('my-bucket-name') # 直接列出需要处理的目标文件名 target_files = {'BPR2.csv', 'BPR6.csv', 'BPRC.csv', 'BPUU.csv', 'TAP000.csv', 'TAP020.csv'} def get_rowcount_csv(): 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] if filename in target_files: s3_path = f's3://my-bucket-name/{my_bucket_object.key}' df = pd.read_csv(s3_path, sep='|') numlines = len(df) print(f'{filename}: {numlines}') get_rowcount_csv()
额外优化建议
- 使用集合存储目标文件名(如方案二),因为集合的成员判断速度比列表快,当目标文件数量多的时候更高效。
- 如果CSV文件很大,用
pd.read_csv读取整个文件统计行数会占用较多内存,也可以改用逐行读取的方式统计:# 替换pd.read_csv那部分代码 import csv from io import StringIO obj = s3.Object('my-bucket-name', my_bucket_object.key) body = obj.get()['Body'].read().decode('utf-8') csv_reader = csv.reader(StringIO(body), delimiter='|') numlines = sum(1 for row in csv_reader) - 1 # 减1是排除表头行,根据需求调整
内容的提问来源于stack exchange,提问作者Lilcodemuffin
相关产品推荐
相关产品推荐

