如何将 AWS S3 上的文本文件导入 pandas 而不写入磁盘

2025-03-18 08:54:00
admin
原创
56
摘要:问题描述:我在 S3 上保存了一个文本文件,它是一个制表符分隔的表格。我想将其加载到 pandas 中,但由于我在 heroku 服务器上运行,因此无法先保存它。以下是我目前所拥有的。import io import boto3 import os import pandas as pd os.enviro...

问题描述:

我在 S3 上保存了一个文本文件,它是一个制表符分隔的表格。我想将其加载到 pandas 中,但由于我在 heroku 服务器上运行,因此无法先保存它。以下是我目前所拥有的。

import io
import boto3
import os
import pandas as pd

os.environ["AWS_ACCESS_KEY_ID"] = "xxxxxxxx"
os.environ["AWS_SECRET_ACCESS_KEY"] = "xxxxxxxx"

s3_client = boto3.client('s3')
response = s3_client.get_object(Bucket="my_bucket",Key="filename.txt")
file = response["Body"]


pd.read_csv(file, header=14, delimiter="    ", low_memory=False)

错误是

OSError: Expected file path name or file-like object, got <class 'bytes'> type

如何将响应主体转换为 Pandas 可以接受的格式?

pd.read_csv(io.StringIO(file), header=14, delimiter="    ", low_memory=False)

returns

TypeError: initial_value must be str or None, not StreamingBody

pd.read_csv(io.BytesIO(file), header=14, delimiter="    ", low_memory=False)

returns

TypeError: 'StreamingBody' does not support the buffer interface

更新-使用以下方法有效

file = response["Body"].read()

pd.read_csv(io.BytesIO(file), header=14, delimiter="    ", low_memory=False)

解决方案 1:

pandas使用botofor read_csv,因此您应该能够:

import boto
data = pd.read_csv('s3://bucket....csv')

如果你需要boto3,因为你在python3.4+,你可以

import boto3
import io
s3 = boto3.client('s3')
obj = s3.get_object(Bucket='bucket', Key='key')
df = pd.read_csv(io.BytesIO(obj['Body'].read()))

自0.20.1 版本 pandas使用以来s3fs,请参阅下面的答案。

解决方案 2:

现在pandas 可以处理 S3 URL 了。你可以简单地执行以下操作:

import pandas as pd
import s3fs

df = pd.read_csv('s3://bucket-name/file.csv')

s3fs如果您没有, 则需要安装。pip install s3fs

验证

如果您的 S3 存储桶是私有的并且需要身份验证,则您有两种选择:

1- 将访问凭证添加到您的~/.aws/credentials配置文件

[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

或者

2- 设置以下环境变量及其适当的值:

  • aws_access_key_id

  • aws_secret_access_key

  • aws_session_token

解决方案 3:

最新的 Pandas 现已支持此功能。请参阅

http://pandas.pydata.org/pandas-docs/stable/io.html#reading-remote-files

例如。,

df = pd.read_csv('s3://pandas-test/tips.csv')

解决方案 4:

对于 Python 3.6+,Amazon 现在有一个非常好的库可以将 Pandas 与其服务一起使用,称为awswrangler。

import awswrangler as wr
import boto3


# Boto3 session
session = boto3.session.Session(aws_access_key_id='XXXX', 
                                aws_secret_access_key='XXXX')

# Awswrangler pass forward all pd.read_csv() function args
df = wr.s3.read_csv(path='s3://bucket/path/',
                    boto3_session=session,
                    skiprows=2,
                    sep=';',
                    decimal=',',
                    na_values=['--'])

要安装 awswrangler:pip install awswrangler

解决方案 5:

使用s3fs可以按如下方式完成:

import s3fs
import pandas as pd
fs = s3fs.S3FileSystem(anon=False)

# CSV
with fs.open('mybucket/path/to/object/foo.pkl') as f:
    df = pd.read_csv(f)

# Pickle
with fs.open('mybucket/path/to/object/foo.pkl') as f:
    df = pd.read_pickle(f)

解决方案 6:

由于文件可能太大,将它们全部加载到数据框中并不明智。因此,逐行读取并将其保存在数据框中。是的,我们也可以在 read_csv 中提供块大小,但我们必须维护读取的行数。

因此我想出了这个工程:

def create_file_object_for_streaming(self):
        print("creating file object for streaming")
        self.file_object = self.bucket.Object(key=self.package_s3_key)
        print("File object is: " + str(self.file_object))
        print("Object file created.")
        return self.file_object

for row in codecs.getreader(self.encoding)(self.response[u'Body']).readlines():
            row_string = StringIO(row)
            df = pd.read_csv(row_string, sep=",")

一旦工作完成,我也会删除 df。
del df

解决方案 7:

对于文本文件,您可以将以下代码与竖线分隔的文件一起使用,例如:-

import pandas as pd
import io
import boto3
s3_client = boto3.client('s3', use_ssl=False)
bucket = #
prefix = #
obj = s3_client.get_object(Bucket=bucket, Key=prefix+ filename)
df = pd.read_fwf((io.BytesIO(obj['Body'].read())) , encoding= 'unicode_escape', delimiter='|', error_bad_lines=False,header=None, dtype=str)

解决方案 8:

import s3fs
import pandas as pd
s3 = s3fs.S3FileSystem(profile='<profile_name>')
pd.read_csv(s3.open(<s3_path>))

解决方案 9:

import os
import pandas as pd
import boto3

session = boto3.Session(profile_name="test")

os.environ['AWS_ACCESS_KEY_ID'] = session.get_credentials().access_key
os.environ['AWS_SECRET_ACCESS_KEY'] = session.get_credentials().secret_key

这样,您就可以使用存储在 ~/.aws/credentials 中的任何配置文件(AWS 帐户)

df = pd.read_csv("s3://xxxx.csv")

解决方案 10:

一种选择是将 csv 转换为 json df.to_dict(),然后将其存储为字符串。请注意,这仅在不需要 CSV 而只想快速将数据框放入 S3 存储桶并再次检索时才有意义。

from boto.s3.connection import S3Connection
import pandas as pd
import yaml

conn = S3Connection()
mybucket = conn.get_bucket('mybucketName')
myKey = mybucket.get_key("myKeyName")

myKey.set_contents_from_string(str(df.to_dict()))

这会将 df 转换为 dict 字符串,然后将其作为 json 保存在 S3 中。您稍后可以以相同的 json 格式读取它:

df = pd.DataFrame(yaml.load(myKey.get_contents_as_string()))

其他解决方案也不错,但这个更简单一些。Yaml 可能不是必需的,但您需要一些东西来解析 json 字符串。如果 S3 文件不一定需要是 CSV,这可以快速修复。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用