簡體   English   中英

將 pandas 數據幀作為壓縮的 CSV 直接寫入 Amazon s3 存儲桶?

[英]Write pandas dataframe as compressed CSV directly to Amazon s3 bucket?

我目前有一個腳本可以讀取保存到 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,而無需制作本地副本。

這是使用 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())

使用 smart-open ( 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)

如果你想要流式寫入(不在內存中保存(解)壓縮的 CSV),你可以這樣做:

import s3fs
import io
import gzip

    def write_df_to_s3(df, filename, path):
        s3 = s3fs.S3FileSystem(anon=False)
        with s3.open(path, 'wb') as f:
            gz = gzip.GzipFile(filename, mode='wb', compresslevel=9, fileobj=f)
            buf = io.TextIOWrapper(gz)
            df.to_csv(buf, index=False, encoding='UTF_8')
            gz.flush()
            gz.close()

在解決此問題之前需要 TextIOWrapper: https ://github.com/pandas-dev/pandas/issues/19827

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM