notebookからAWS S3へのデータ保存形式を比較してみた (Parquet、君に決めた!)

2 min read読了の目安(約2300字

はじめに

Pythonでデータ分析をやっていると、完成したDataFrameや作業途中のDataFrameをS3に保存したくなるときがあります。これまでは、CSVでしか保存してなかった(それしか知らなかったから)けど、ZIPやPqrquetで保存する方式があることを知りパフォーマンスを比較してみました。実験の結果、実務上はParquetを使うのが良さそうです。
※AWS SageMakerのノートブックからAWS S3への保存を想定しています

比較した形式

  1. CSV
  2. GZIP
  3. Parquet

実験結果
例として、.csvでは487.5MB相当のDataFrameを各形式でS3に保存した時のパフォーマンスをまとめました。Parquetの実行速度が最速で、GZIPには及ばないがかなりデータ圧縮できているようです。

形式 実行速度[s] Filesize[MB] データ圧縮率
.csv 121 487.5 1.00
.csv.gzip 181 91.8 0.19
.parq 9 108.4 0.22

CSVで保存する

import pandas as pd
from io import StringIO
import os

def csv_upload_to_S3(df, fileName):
    csv_buffer = StringIO()
    df.to_csv(csv_buffer)
    s3 = boto3.resource('s3')
    s3_obj = s3.Object('bucket_name', os.path.join('prefix', fileName))
    result = s3_obj.put(Body=csv_buffer.getvalue())
    return result

保存したいDataFrameと保存先のバケット名、プレフィックスとファイル名を指定する。

%%time
csv_upload_to_S3(DataFrame_name,"filename.csv")

CPU times: user 1min 54s, sys: 1.17 s, total: 1min 55s
Wall time: 2min 1s

これがベンチマークです。早くはない印象。S3に保存されているファイルサイズは487.5MB。

ZIP(GZIP)で保存する

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

def save_to_s3_gzip(df: pd.DataFrame, bucket: str, key: str):
    buffer = BytesIO()
    with gzip.open(buffer, mode='wt') as f:
        df.to_csv(f)
    s3 = boto3.client('s3')
    s3.put_object(Bucket=bucket, Key=key, Body=buffer.getvalue())

保存したいDataFrameと保存先のバケット名、プレフィックスとファイル名を指定する。

save_to_s3_gzip(DataFrame_name, 'bucket-name', 'prefix/filename.csv.gzip')

CPU times: user 3min, sys: 154 ms, total: 3min
Wall time: 3min 1s

実行時間が伸びている。一方でS3に保存されているファイルサイズは91.8MBで圧縮率は19%。

Parquetで保存する

公式ドキュメントを参考に

awswranglerを入れてなければpip install

!pip install awswrangler

以下を実行すればOK

import pandas as pd
import awswrangler as wr

%%time
wr.s3.to_parquet(
    df=DataFrame_name,
    path='s3://bucket/prefix/filename.parquet',
)

CPU times: user 8.69 s, sys: 1.42 s, total: 10.1 s
Wall time: 9.18 s

爆速!!!!え、はや!!!
S3に保存されているファイルサイズも108.4MBで圧縮率は22%。ZIPほどの圧縮率ではないけど、かなり圧縮されているし、何より実行速度が素晴らしいのでParquetを使ってみようと思います。さらばCSV。

圧縮形式も指定できるようなので、さらにいろいろ試してみようと思います。