如何使用pd.read_csv()读取GCS存储桶中的Blob对象文件
正确读取GCS Blob内容供pandas解析的实现方案
原代码的核心问题有两个:
- 调用的
download_to_file()方法需要传入一个处于写打开状态的文件对象,且该方法无返回值,直接将其返回结果传给pd.read_csv()无法拿到有效文件对象。 - 传入
/tmp作为下载目标是目录路径,不是有效文件路径,即使方法调用正确也会抛出路径错误。
你可以根据场景选择以下两种实现方式:
方案1:内存直读(无本地IO,推荐批量小文件场景)
直接调用Blob对象的download_as_bytes()方法拿到文件的二进制内容,用BytesIO包装为pandas可识别的类文件对象即可,不需要落地到本地磁盘:
from google.cloud import storage import pandas as pd from io import BytesIO client = storage.Client.from_service_account_json('sa.json') BUCKET_NAME = 'sleep-accel' bucket = client.get_bucket(BUCKET_NAME) # 过滤掉目录占位项:list_blobs会将前缀对应的目录本身也作为Blob返回,名称以/结尾,无实际内容 blobs_specific = [ blob for blob in bucket.list_blobs(prefix='physionet.org/files/sleep-accel/1.0.0/motion/') if not blob.name.endswith('/') ] main_df = pd.DataFrame() for blob in blobs_specific: content = blob.download_as_bytes() # 如果你的txt是制表符/空格分隔,自行添加sep参数,比如sep='\t' 或 sep='\s+' current_df = pd.read_csv(BytesIO(content)) main_df = pd.concat([main_df, current_df], ignore_index=True)
方案2:下载到本地文件后读取
如果文件体积较大不适合全量加载到内存,可以先将文件下载到本地有效路径,再传给pandas读取:
import os for blob in blobs_specific: # 提取文件名,拼接本地临时路径 file_name = os.path.basename(blob.name) local_path = f"/tmp/{file_name}" # 用download_to_filename直接传本地文件路径即可,不需要手动打开文件 blob.download_to_filename(local_path) current_df = pd.read_csv(local_path) main_df = pd.concat([main_df, current_df], ignore_index=True) # 处理完可以按需删除本地临时文件 os.remove(local_path)
补充说明
- 若使用新版依赖环境,也可直接用
pd.read_csv(f"gs://{BUCKET_NAME}/{blob.name}")的路径形式直接读取,该方式需要提前安装gcsfs库,且服务账号需具备对应存储桶的读取权限。 - 批量合并DataFrame时建议添加
ignore_index=True参数,避免索引重复引发后续数据处理异常。 - 若待读取的txt文件不是逗号分隔格式,需在
pd.read_csv()中传入对应sep参数:制表符分隔传sep='\t',任意空白分隔传sep='\s+'。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

