从S3不同文件夹拉取文件 按类型合并为DataFrame
解决方案
整体思路
先获取S3存储桶内所有目标文件,按文件名分组,再逐个读取每组内的文件,最终合并成单个DataFrame。针对你30种文件、20个文件夹的场景,这个逻辑可以高效批量处理。
前置准备
先安装必要依赖:
pip install boto3 pandas openpyxl
注:
openpyxl是pandas读取xlsx文件的必需依赖,不能省略。
完整可运行代码
import boto3 import pandas as pd from io import BytesIO # 初始化S3客户端(新手用客户端比资源方式更直观) s3_client = boto3.client('s3') bucket_name = 'your-bucket-name' # 替换成你的桶名称 root_prefix = "data/file/folder/" # 替换成你的根路径前缀 # 存储每个文件名对应的DataFrame列表,用于后续合并 file_df_groups = {} # 分页获取S3内的文件(避免文件过多时单次请求返回不全) paginator = s3_client.get_paginator('list_objects_v2') response_pages = paginator.paginate(Bucket=bucket_name, Prefix=root_prefix) for page in response_pages: # 跳过空目录 if 'Contents' not in page: continue for obj in page['Contents']: obj_key = obj['Key'] # 跳过文件夹本身(S3的文件夹是虚拟对象,以/结尾) if obj_key.endswith('/'): continue # 提取文件名(不管文件在哪个子文件夹,只取最后一段) file_name = obj_key.split('/')[-1] # 读取S3文件到内存,不下载到本地 try: s3_file = s3_client.get_object(Bucket=bucket_name, Key=obj_key) # 将二进制数据流转为pandas可读取的格式 df = pd.read_excel(BytesIO(s3_file['Body'].read())) # 把当前文件的DataFrame加入对应分组 if file_name not in file_df_groups: file_df_groups[file_name] = [] file_df_groups[file_name].append(df) except Exception as e: print(f"处理文件 {obj_key} 失败: {str(e)}") # 合并每个文件名对应的所有DataFrame merged_results = {} for name, df_list in file_df_groups.items(): if df_list: # 按行合并,ignore_index重置索引避免重复 merged_df = pd.concat(df_list, ignore_index=True) merged_results[name] = merged_df print(f"完成合并:{name},共合并 {len(df_list)} 个文件") # 示例:查看合并后的A.xlsx数据 if 'A.xlsx' in merged_results: print("\n合并后的A.xlsx前5行:") print(merged_results['A.xlsx'].head())
关键细节说明
- 分页获取文件:用
list_objects_v2的分页器,解决文件数量过多时单次请求返回不全的问题,适合你的600个文件场景。 - 内存读取:通过
BytesIO直接读取S3的二进制数据流,不用下载文件到本地,节省磁盘空间和时间。 - 分组逻辑:通过
split('/')[-1]提取文件名,不管文件在Name202301还是Name202302文件夹,同名文件都会自动归为一组。 - 异常处理:单个文件读取失败时不会中断整个程序,还会打印错误信息方便排查。
新手必看注意事项
- AWS凭证配置:确保你的环境已经配置好AWS访问凭证,可以通过
~/.aws/credentials文件,或者设置AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY环境变量。 - 文件格式一致性:如果同名文件的列结构不一致(比如有的多列、少列),合并时会报错。可以在
pd.read_excel里加usecols参数指定统一的列,或者提前处理文件格式。 - 权限检查:确认你的AWS账号有目标S3桶的
list和get权限,否则会出现访问被拒绝的错误。
内容的提问来源于stack exchange,提问作者ma0ma0
相关产品推荐
相关产品推荐

