使用Pandas从S3读取Parquet文件报错,PySpark可正常读取求解决
问题原因
你遇到的NoSuchKey错误核心原因是:
- PySpark的
spark.read.parquet会自动识别S3路径对应的目录,加载目录下所有的Parquet分片文件(比如part-00000.parquet这类); - 但boto3的
get_object要求传入单个具体文件的完整Key,你传入的data/wine_dataset是目录路径,不是单个文件,所以S3找不到对应的Key。
解决方案
推荐以下几种解决方式:
方法1:直接用Pandas的S3文件系统支持(最简单)
Pandas可以通过s3fs库直接读取S3上的Parquet目录,不需要手动调用boto3:
import pandas as pd # 配置AWS凭证(也可以通过环境变量、~/.aws/credentials等方式配置) aws_credentials = { 'key': 'your_access_key', 'secret': 'your_secret_key', 'region_name': 'your_region' } # 直接读取S3目录 df = pd.read_parquet( 's3://bucket_name/data/wine_dataset', storage_options=aws_credentials ) print(df)
注意:需要先安装依赖包pip install s3fs pyarrow(pyarrow是Parquet解析依赖)。
方法2:用boto3遍历目录文件后合并读取
如果一定要用boto3手动处理,可以先列出目录下的所有Parquet文件,再逐个读取合并:
import boto3 import pandas as pd key = 'your_access_key' secret = 'your_secret_key' s3_client = boto3.client( 's3', aws_access_key_id=key, aws_secret_access_key=secret, region_name='your_region' ) AWS_S3_BUCKET = 'bucket_name' prefix = 'data/wine_dataset/' # 注意末尾加斜杠,确保匹配目录下的文件 # 列出目录下所有文件 response = s3_client.list_objects_v2(Bucket=AWS_S3_BUCKET, Prefix=prefix) file_keys = [obj['Key'] for obj in response['Contents'] if not obj['Key'].endswith('/')] # 逐个读取并合并DataFrame dfs = [] for file_key in file_keys: obj = s3_client.get_object(Bucket=AWS_S3_BUCKET, Key=file_key) df_part = pd.read_parquet(obj['Body']) dfs.append(df_part) final_df = pd.concat(dfs, ignore_index=True) print(final_df)
方法3:检查路径大小写问题
S3的对象Key是大小写敏感的,而Spark可能通过配置忽略了大小写差异。确认你的filePath中的目录/文件名大小写和S3上的完全一致,比如Data/Wine_Dataset和data/wine_dataset是两个不同的Key。
内容的提问来源于stack exchange,提问作者merkle
相关产品推荐
相关产品推荐

