【问题标题】:Import latest file from S3 bucket to Pandas dataframe将最新文件从 S3 存储桶导入 Pandas 数据框
【发布时间】:2021-04-04 05:51:33
【问题描述】:

情况

我在 Python 3 中编写了一些代码,其中我使用 OS 和 Glob 包在目录中查找最新的 csv 文件并将其转换为 Panda 数据帧。

代码如下:

import pandas as pd
from pathlib import Path
import glob
import os

# LOOK FOR ALL CSVs IN FOLDER AND GET LATEST
fld = '.'
latest_csv_file = glob.glob('/path/to/file/filename.csv')

imported_file = max(latest_csv_file, key=os.path.getctime)


# IMPORT LATEST CV USING PANDAS
imported_file = pd.read_csv(latest_csv_file, dtype={2:'str'})


# REMOVE SPACES FROM COL NAMES AND CONVERT COL NAMES TO LOWER CASE
imported_file.columns = imported_file.columns.str.replace(' ', '')
imported_file.columns = imported_file.columns.str.lower()

这似乎运作良好,但是我需要能够在我的 Lambda 函数中执行相同的操作,该函数会保存来自传入电子邮件的 csv 文件附件。

我已经尝试过什么

 bucketname = 'my_bucket' 
    
    
 s3_client = boto3.client('s3')
 response = s3_client.list_objects_v2(Bucket = bucketname2, Prefix = 'attachments/')
 all = response['Contents']      
 latest_file = max(all, key=lambda x: x['LastModified'])
    
 print(latest_file)

这将为我提供以下格式的文件名

附件/nolu34lqipv1cl14i0qjebcc1rnqb2ngbnf4ss01-filename.csv

[文件夹]/[original_msg_key]-[filename.csv]

但是,如果我尝试将文件读入 Pandas df,我会得到以下结果

imported_file = pd.read_csv(latest_file, dtype={2:'str'})

模块初始化错误无效的文​​件路径或缓冲区对象类型:

我理解这是因为 Pandas 需要一个特定的文件路径而不是 'dict' 类型的对象,但看不到如何实现我的目标。

任何帮助表示赞赏。

【问题讨论】:

    标签: python-3.x pandas amazon-web-services amazon-s3 boto3


    【解决方案1】:

    要获取对象的键,您必须使用 latest_file['Key'],对于 pandas,您应该包括 s3:// 作为前缀:

    imported_file = pd.read_csv('s3://' + latest_file['Key'], dtype={2:'str'})
    

    这需要为您的 python 正确设置 s3fs 以及用于 S3 访问的 AWS 凭证。

    您还有bucketname2,应该使用bucketname

    【讨论】:

    • 感谢@Marcin。这就是所谓的“挂载”一个 S3 存储桶吗?
    • @jimiclapton 我认为“挂载”是指s3fuse 的使用,其中 s3 看起来就像操作系统中的任何其他文件夹,供所有应用程序使用。但是s3fs 只是一个特定于 python 和 pandas 的 s3 接口。
    • 有趣,好的。尝试使用 sudo pip install s3fs 通过 Cloud9 安装并获得安装成功消息,但使用 import s3fs 时 lambda 错误日志显示 Unable to import module 'lambda_function': No module named 's3fs'
    • 是否有可能必须将其导入并用作 Lambda 函数中的一个层,就像我必须安装 Pandas 一样?
    【解决方案2】:

    你应该可以在 lambda 中使用它。将其添加到您现有的代码中

    bucketname = 'my_bucket'  
    s3_client = boto3.client('s3')
    key = latest_file #validate this is the full key path
    
    obj = s3_client.get_object(Bucket=bucketname, Key=key)
    data = io.StringIO(obj['Body'].read().decode('utf-8'))
    pd.read_csv(data) # use additional arguments as needed
    

    【讨论】:

    • 感谢@Jonathan Leon 的贡献,我会试试这个。你可能是说obj = s3_client.get_object(Bucket=bucketname, Key=key)。我相信否则这会引发not defined 错误。
    • 是的,当我复制代码时,我没有发现我的代码与你的代码相比发生了变化。更新了代码以反映它。
    猜你喜欢
    • 2020-07-29
    • 2016-06-18
    • 2017-11-23
    • 2022-01-23
    • 2022-11-17
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多