【问题标题】:How to read a csv file from an s3 bucket using Pandas in Python如何在 Python 中使用 Pandas 从 s3 存储桶中读取 csv 文件
【发布时间】:2015-08-29 08:45:47
【问题描述】:

我正在尝试使用以下代码将位于 AWS S3 存储桶中的 CSV 文件作为 pandas 数据帧读入内存:

import pandas as pd
import boto

data = pd.read_csv('s3:/example_bucket.s3-website-ap-southeast-2.amazonaws.com/data_1.csv')

为了提供完全访问权限,我在 S3 存储桶上设置了存储桶策略,如下所示:

{
"Version": "2012-10-17",
"Id": "statement1",
"Statement": [
    {
        "Sid": "statement1",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::example_bucket"
    }
]

}

不幸的是,我仍然在 python 中收到以下错误:

boto.exception.S3ResponseError: S3ResponseError: 405 Method Not Allowed

想知道是否有人可以帮助解释如何在 AWS S3 中正确设置权限或正确配置 pandas 以导入文件。谢谢!

【问题讨论】:

  • s3后面不应该有双斜线吗?
  • 是的,你说得对,应该有。我还必须更改存储桶和文件的位置:tripData = pd.read_csv('htps://s3-ap-southeast-2.amazonaws.com/example_bucket/data.csv')。我必须更新单个文件的权限。但它现在有效。干杯。
  • 请将您的解决方案添加为帮助其他 Stackoverflow 用户的答案。
  • 使用read_csv从s3读取文件时,pandas是先本地下载到磁盘再加载到内存吗?还是从网络直接流入内存?

标签: python amazon-web-services pandas amazon-s3


【解决方案1】:

使用熊猫 0.20.3

import os
import boto3
import pandas as pd
import sys

if sys.version_info[0] < 3: 
    from StringIO import StringIO # Python 2.x
else:
    from io import StringIO # Python 3.x

# get your credentials from environment variables
aws_id = os.environ['AWS_ID']
aws_secret = os.environ['AWS_SECRET']

client = boto3.client('s3', aws_access_key_id=aws_id,
        aws_secret_access_key=aws_secret)

bucket_name = 'my_bucket'

object_key = 'my_file.csv'
csv_obj = client.get_object(Bucket=bucket_name, Key=object_key)
body = csv_obj['Body']
csv_string = body.read().decode('utf-8')

df = pd.read_csv(StringIO(csv_string))

【讨论】:

  • 当我以这种方式导入时,df 的列不会出现?
  • 我正在尝试这个,我在 os.environ 的 id 和密钥调用中遇到错误 - 这是我必须在终端中设置的东西吗?
  • @ZachOakes 是的,这是您需要设置的。这两行假设您的 ID 和 SECRET 之前已保存为环境变量,但您不需要从环境变量中提取它们。相反,您可以用您喜欢的任何方法替换这两行,以便将您的 ID 和 SECRET 放入您的代码中。
  • 也适用于 DictReader:reader = csv.DictReader(io.StringIO(body), fieldnames=fieldnames)
【解决方案2】:

基于 this answer 建议使用 smart_open 从 S3 读取,这就是我在 Pandas 中使用它的方式:

import os
import pandas as pd
from smart_open import smart_open

aws_key = os.environ['AWS_ACCESS_KEY']
aws_secret = os.environ['AWS_SECRET_ACCESS_KEY']

bucket_name = 'my_bucket'
object_key = 'my_file.csv'

path = 's3://{}:{}@{}/{}'.format(aws_key, aws_secret, bucket_name, object_key)

df = pd.read_csv(smart_open(path))

【讨论】:

    【解决方案3】:

    你不需要pandas..你可以使用python的默认csv库

    def read_file(bucket_name,region, remote_file_name, aws_access_key_id, aws_secret_access_key):
        # reads a csv from AWS
    
        # first you stablish connection with your passwords and region id
    
        conn = boto.s3.connect_to_region(
            region,
            aws_access_key_id=aws_access_key_id,
            aws_secret_access_key=aws_secret_access_key)
    
        # next you obtain the key of the csv you want to read
        # you will need the bucket name and the csv file name
    
        bucket = conn.get_bucket(bucket_name, validate=False)
        key = Key(bucket)
        key.key = remote_file_name
        data = key.get_contents_as_string()
        key.close()
    
        # you store it into a string, therefore you will need to split it
        # usually the split characters are '\r\n' if not just read the file normally 
        # and find out what they are 
    
        reader = csv.reader(data.split('\r\n'))
        data = []
        header = next(reader)
        for row in reader:
            data.append(row)
    
        return data
    

    希望它能解决你的问题, 祝你好运! :)

    【讨论】:

      【解决方案4】:

      我最终意识到,您还需要为存储桶中的每个单独对象设置权限,以便使用以下代码提取它:

      from boto.s3.key import Key
      k = Key(bucket)
      k.key = 'data_1.csv'
      k.set_canned_acl('public-read')
      

      而且我还得修改pd.read_csv命令中的bucket地址,如下:

      data = pd.read_csv('https://s3-ap-southeast-2.amazonaws.com/example_bucket/data_1.csv')
      

      【讨论】:

      • 如何修改地址成为pandas可以读取的url?
      • 您已使世界上任何人都可以阅读此文件,而大多数人可能应该避免这样做。上面@jpobst 的回答提供了读取文件的正确凭据,这是大多数人应该做的。
      猜你喜欢
      • 1970-01-01
      • 2021-10-25
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多