Python/NumPy | Pandas

[Pandas] S3에 gz 압축 DataFrame csv 업로드하기

비번변경 2024. 11. 8. 16:02

개요

Pandas로 처리한 DataFrame을 압축한 CSV 형태로 S3에 업로드하고 싶다. 가능하면 CSV 파일을 파일 시스템에 남기지 않을 수 있었으면 좋겠다. 적절한 방법이 있는지 찾아보자.

 

 

테스트 데이터

이전에 S3에 저장했던 아래 데이터를 사용하여 테스트해 본다.

one, 1
two, 2
three, 3

 

 

코드

DataFrame의 CSV 형식 데이터를 gz 압축 파일 객체에 쓰고, 압축 파일 객체의 값을 S3에 업로드하는 방식으로 문제를 해결할 수 있다. 

 

1. 압축할 DataFrame 로드

import boto3
import pandas as pd

bucket = 'BUCKET_NAME'
prefix = 'PREFIX'
filename = 'FILE_NAME

# 압축할 파일 로드
df = pd.read_csv(f's3://{bucket}/{prefix}/{filename}')

당연한 말이지만…… 꼭 CSV 파일을 로드할 필요는 없다.

 

2. 파일 압축

Gzip 압축 파일 객체에 DataFrame을 CSV 형식으로 쓴다. 파일시스템에 파일을 남기려는 것은 아니기 때문에 GzipFile 객체 생성 시 filename이 아니라 fieobj에 BytesIO 등을 전달한다. 

import gzip
from io import BytesIO
from io import TextIOWrapper

# 압축
csv_buffer = BytesIO()
with gzip.GzipFile(mode='w', fileobj=csv_buffer) as zipped_file:
    df.to_csv(TextIOWrapper(zipped_file, 'utf-8-sig'), index=False)

 

3. S3에 업로드

S3 resource 객체를 활용하여 Object를 put 한다. put 할 때 객체 본문은 Gzip 파일 객체의 값으로 전달한다.

 

# s3에 업로드
s3 = boto3.resource('s3')
result = s3.Object(bucket, f'{prefix}/{filename}.gz').put(Body=csv_buffer.getvalue())

 

 

테스트 결과

실행해 보면 정상적으로 원하던 gz 형식 압축 파일이 생성된 것을 확인할 수 있다.

 

 

참고 문서

https://stackoverflow.com/questions/43729224/write-pandas-dataframe-as-compressed-csv-directly-to-amazon-s3-bucket

https://stackoverflow.com/questions/61253928/writing-pandas-dataframe-to-s3-bucket-aws

https://stackoverflow.com/questions/38154040/save-dataframe-to-csv-directly-to-s3-python