web-dev-qa-db-ja.com

boto3を使用してS3バケットから複数のcsvファイルを読み取る

pythonのboto3を使用してS3バケットから複数のcsvファイルを読み取り、最後にそれらのファイルをパンダの単一のデータフレームに結合する必要があります。

私はPythonで次のスクリプトから単一のファイルを読み取ることができます

 s3 = boto3.resource('s3')
 bucket = s3.Bucket('test-bucket')
 for obj in bucket.objects.all():
    key = obj.key
    body = obj.get()['Body'].read()

以下は私の道です

 files/splittedfiles/Code-345678

Code-345678複数のcsvファイルがあり、それらを読み取ってパンダの単一のデータフレームに結合する必要があります

また、選択したCodesのリストをリストとして渡して、それらのフォルダーのみを読み取るにはどうすればよいですか。例えば.

files/splittedfiles/Code-345678
files/splittedfiles/Code-345679
files/splittedfiles/Code-345680
files/splittedfiles/Code-345681
files/splittedfiles/Code-345682

上記から、次のコードでのみファイルを読み取る必要があります。

345678,345679,345682

Pythonでどうすればいいですか?

3
Neil

_boto3_ APIは、一度に複数のオブジェクトを読み取ることをサポートしていません。できることは、指定されたプレフィックスを持つすべてのオブジェクトを取得し、返された各オブジェクトをループでロードすることです。これを行うには、filter()メソッドを使用し、Prefixパラメーターをロードするオブジェクトのプレフィックスに設定します。以下では、コードにこの簡単な変更を加えました。これにより、プレフィックスが「files/splittedfiles/Code-345678」のすべてのオブジェクトを取得できます。これらのオブジェクトをループして、各ファイルをDataFrameにロードできます。

_s3 = boto3.resource('s3')
bucket = s3.Bucket('test-bucket')
prefix_objs = bucket.objects.filter(Prefix="files/splittedfiles/Code-345678")
for obj in prefix_objs:
    key = obj.key
    body = obj.get()['Body'].read()
_

評価したいプレフィックスが複数ある場合は、上記を使用して、プレフィックスがパラメーターである関数に変換し、結果を組み合わせることができます。関数は次のようになります。

_import pandas as pd

def read_prefix_to_df(prefix):
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('test-bucket')
    prefix_objs = bucket.objects.filter(Prefix=prefix)
    prefix_df = []
    for obj in prefix_objs:
        key = obj.key
        body = obj.get()['Body'].read()
        df = pd.DataFrame(body)
        prefix_df.append(df)
    return pd.concat(prefix_df)
_

次に、この関数を各プレフィックスに繰り返し適用し、最終的に結果を組み合わせることができます。

7
vealkind

「all」の代わりに「filter」を使用して、このように実行できますか?

for obj in bucket.objects.filter(Prefix='files/splittedfiles/'):
    key = obj.key
    body = obj.get()['Body'].read()
1