从 AWS 胶水上的 S3 读取 csv 和文本文件而无需将其读取为动态 daataframe 的最佳方法是什么?



我正在尝试读取 S3 存储桶中的 csv 文件。我想做一些操作,然后最终转换为动态数据帧并将其写回 S3。

这是我到目前为止尝试过的:

纯蟒蛇:

Val1=""
Val2=""
cols=[]
width=[]
with open('s3://demo-ETL/read/data.csv') as csvfile:
readCSV = csv.reader(csvfile, delimiter=',')
for row in readCSV:
print(row)
if ((Val1=="" ) & (Val2=="")):
Val1=row[0]
Val2=row[0]
cols.append(row[1])
width.append(int(row[4]))
else:
continues...

在这里,我收到一个错误,说它根本无法在目录中找到该文件。

肉毒杆菌3:

import boto3
s3 = boto3.client('s3')
data = s3.get_object(Bucket='demo-ETL', Key='read/data.csv')
contents = data['Body'].read()
print(contents)
for row in content:
if ((Val1=="" ) & (Val2=="")):
Val1=row[0]
Val2=row[0]
cols.append(row[1])
width.append(int(row[4]))
else:
continues...

这里它说索引超出了范围,这很奇怪,因为我在 csv 文件中有 4 个逗号分隔的值。当我查看 print(内容(的结果时,我看到它将每个字符放在一个列表中,而不是将每个逗号分隔的值放在一个列表中。

有没有更好的方法来从 s3 读取 csv?

我最终通过将其读取为熊猫数据帧来解决这个问题。我首先使用 boto3 创建了一个对象,然后将整个对象读取为 pd,然后将其转换为列表。

s3 = boto3.resource('s3') 
bucket = s3.Bucket('demo-ETL')
obj = bucket.Object(key='read/data.csv') 
dataFrame = pd.read_csv(obj.get()['Body'])
l = dataFrame.values.tolist()
for i in l:
print(i)

get_object返回类型为StreamingBodyBody响应值。根据文档,如果您尝试逐行进行,则可能需要使用iter_lines

例如:

import boto3
s3 = boto3.client('s3')
data = s3.get_object(Bucket='demo-ETL', Key='read/data.csv')
file_lines = data['Body'].iter_lines()
print(file_lines)

这可能会做更多你想要的。

您可以使用 Spark 像这样读取文件:

df = spark.read.
format("csv").
option("header", "true").
load("s3://bucket-name/file-name.csv")

您可以在此处找到更多选项:https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.DataFrameReader.csv

最新更新