我目前有一个脚本,它读取保存到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而不用制作本地副本。
答案 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)