Какой самый быстрый способ сохранить большой пандан DataFrame на S3? - PullRequest
1 голос
/ 28 марта 2019

Я пытаюсь выяснить, какой самый быстрый способ записать БОЛЬШОЙ pandas DataFrame в файловую систему S3. В настоящее время я пытаюсь двумя способами:

1) Через сжатие gzip (BytesIO) и boto3

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(bucket, s3_path + name_zip)
s3_object.put(Body=gz_buffer.getvalue())

, что для кадра данных из 7M строк занимает около 420 секунд для записи в S3.

2) Через запись в CSV-файл без сжатия (буфер StringIO)

csv_buffer = StringIO()
data.to_csv(csv_buffer)
s3_resource = boto3.resource('s3')
s3_resource.Object(bucket, s3_path + name_csv).put(Body=csv_buffer.getvalue())

, что занимает около 371 секунды ...

Вопрос: Есть ли еще какой-нибудь более быстрый способ записи кадра данных панды в S3?

Ответы [ 3 ]

3 голосов
/ 09 апреля 2019

Используйте загрузку из нескольких частей, чтобы ускорить передачу на S3.Сжатие делает файл меньше, поэтому это тоже поможет.

import boto3
s3 = boto3.client('s3')

csv_buffer = BytesIO()
df.to_csv(csv_buffer, compression='gzip')

# multipart upload
# use boto3.s3.transfer.TransferConfig if you need to tune part size or other settings
s3.upload_fileobj(csv_buffer, bucket, key)

Документы для s3.upload_fileobj находятся здесь: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.upload_fileobj

0 голосов
/ 29 марта 2019

Сначала убедитесь, что вы пишете в корзину, которая находится в той же области , что и ваша записная книжка.

Во-вторых, вы можете попробовать опцию загрузки, используя multi-part , которая принимает файлы размером более нескольких ГБ и загружает их параллельно:

from boto3.s3.transfer import TransferConfig

def s3_upload_file(args):     
    s3 = boto3.resource('s3')

    GB = 1024 ** 3
    config = TransferConfig(multipart_threshold=5 * GB)

    s3.meta.client.upload_file(args.path, args.bucket, os.path.basename(args.path),Config=config)
0 голосов
/ 29 марта 2019

Вы можете попробовать использовать s3fs со pandas сжатием для загрузки на S3.StringIO или BytesIO - это переполнение памяти.

import s3fs
import pandas as pd

s3 = s3fs.S3FileSystem(anon=False)
df = pd.read_csv("some_large_file")
with s3.open('s3://bucket/file.csv.gzip','w') as f:
    df.to_csv(f, compression='gzip')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...