将pandas数据帧直接写为压缩CSV到Amazon s3存储桶?

时间:2017-05-02 02:39:40

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

我目前有一个脚本,它读取保存到s3的现有csv版本,将其与pandas数据帧中的新行组合,然后将其直接写回s3。

    try:
        csv_prev_content = str(s3_resource.Object('bucket-name', ticker_csv_file_name).get()['Body'].read(), 'utf8')
    except:
        csv_prev_content = ''

    csv_output = csv_prev_content + curr_df.to_csv(path_or_buf=None, header=False)
    s3_resource.Object('bucket-name', ticker_csv_file_name).put(Body=csv_output)

有没有办法可以用gzip压缩的csv做到这一点?我想在s3上读取现有的.gz压缩csv(如果有的话),将其与数据帧的内容连接起来,然后直接在s3 中用新的组合压缩csv覆盖.gz而不用制作本地副本。

4 个答案:

答案 0 :(得分:9)

这是使用Pandas 0.20.1在Python 3.5.2中的解决方案。

可以从S3,本地CSV或其他任何内容读取源DataFrame。

import boto3
import gzip
import pandas as pd
from io import BytesIO, TextIOWrapper

df = pd.read_csv('s3://ramey/test.csv')
gz_buffer = BytesIO()

with gzip.GzipFile(mode='w', fileobj=gz_buffer) as gz_file:
    df.to_csv(TextIOWrapper(gz_file, 'utf8'), index=False)

s3_resource = boto3.resource('s3')
s3_object = s3_resource.Object('ramey', 'new-file.csv.gz')
s3_object.put(Body=gz_buffer.getvalue())

答案 1 :(得分:0)

如果要流式写入(不将压缩的CSV保留在内存中),可以执行以下操作:

--sslCAFile
在解决此问题之前,需要

TextIOWrapper:https://github.com/pandas-dev/pandas/issues/19827

答案 2 :(得分:0)

Pandas支持在to_csv()方法中以gzip的形式编写。

安装可选的s3fs依赖项可以使您直接对s3进行读/写:

import pandas as pd


df = pd.read_csv('s3://ramey/test.csv')
df.to_csv('s3://ramey/test.csv.gz', compression='gzip')

答案 3 :(得分:0)

使用智能开放(https://pypi.org/project/smart-open/

有一个更优雅的解决方案
import pandas as pd
from smart_open import open

df.to_csv(open('s3://bucket/prefix/filename.csv.gz','w'),index = False)