引用AWS S3桶内Excel对象时无法两次执行pandas read_excel函数如何解决
报错根因
AWS S3返回的obj['Body']是流式读取对象,第一次调用.read()方法读取完整个文件内容后,流的读取指针会移动到文件末尾,后续再调用.read()只会返回空字节,因此pandas拿到空内容后会识别为不合法的Excel文件。你之前重复调用get_object的方案本质是每次获取新的流对象,虽然能正常运行,但会产生大量不必要的重复网络请求,冗余度高且性能差。
最优实现方案
仅调用一次S3接口拉取完整文件内容存为内存字节变量,后续读取多个工作表时复用该字节内容即可,代码如下:
import pandas as pd import io # 仅拉取一次S3文件,把完整内容存为字节变量 obj = S3_Client.get_object(Bucket=bucket_name, Key=str(XLSX_Keys.iloc[0,0])) excel_bytes = obj['Body'].read() # 读取不同工作表时,直接复用已存储的字节内容 File1 = pd.read_excel(io.BytesIO(excel_bytes), sheet_name="Sheet1", dtype=str, header=4) File2 = pd.read_excel(io.BytesIO(excel_bytes), sheet_name="Sheet2", dtype=str, header=4) File3 = pd.read_excel(io.BytesIO(excel_bytes), sheet_name="Sheet3", dtype=str, header=4)
进阶优化
如果需要读取的工作表数量较多,可以直接一次性读取所有工作表到字典中,减少read_excel的调用次数:
# sheet_name设置为None时,会返回所有工作表组成的字典,key为工作表名,value为对应DataFrame all_sheets = pd.read_excel(io.BytesIO(excel_bytes), sheet_name=None, dtype=str, header=4) # 按需从字典中取对应工作表即可 File1 = all_sheets["Sheet1"] File2 = all_sheets["Sheet2"] File3 = all_sheets["Sheet3"]
该方案既减少了代码冗余,又避免了多次S3请求的网络开销,执行效率远高于原有临时方案。
内容的提问来源于stack exchange,提问作者PKS
相关产品推荐
相关产品推荐

