後で考える

本、旅行、資格、お酒について書くと思います

AWS Lambda で Pandas 使って S3 内の CSV ファイルを読みたい

本記事の目的

表題通りですが、AWS Lambda の関数上で pandas.read_csv() を使って CSV ファイルを読み込みたい。

ネット上では、公開されている Pandas Layer を追加するだけで OK という記事が多かったのですが、自分の場合、それだけでは import できても read_csv が動作しないという問題が発生したので対処法を共有します。

私の Lambda 環境

引っかかったポイント

  • アーキテクチャを arm64 にすると Pandas の import すらできなかった
  • Pandas だけではなく fsspec が必要となる。というか、s3fs が必要
  • s3fsのレイヤーは (探した限り) 配布されていないので、結局自分でレイヤーを作成する必要あり

手順

  1. Pandas Layer を Lambda 関数に追加
  2. s3fs (と、fsspec) をどこかしらで pip install し zip 圧縮
  3. zip ファイルを使ってレイヤーを作成
  4. 作成したレイヤーを Lambda 関数に追加
  5. いざ読み込み

Pandas Layer を Lambda 関数に追加

github.com

ここから該当するランタイム、リージョンの Pandas Layer の ARN をコピーします。

AWS コンソールから使いたい Lambda 関数の「レイヤーの追加」>「ARN の指定」でコピーした ARN を貼り付けて「検証」->「追加」します。

ここまでだと、Pandas の import はできますが、read_csv でエラーが返ってきてしまいました。

エラーの内容を見ると、「fsspec がいないよ!」みたいなことを言っています。誰ですかそれは。

s3fs (と、fsspec) をどこかしらで pip install し zip 圧縮

Pandas とは異なり、 s3fs / fsspec のレイヤーは公開されていない (たぶん) ので、自分で作成する必要があります。

s3fs を install すれば、fsspec も一緒に入ってくれるみたいです。ちょっとこの辺トラブったので間違っていたらすいません。

mkdir python
pip install s3fs -t ./python/
zip -r upload.zip ./python/

Lambda 上では pip install できません。

自分はローカルの Ubuntu でインストールしましたが、EC2 インスタンスなどがあるならそれを利用する手もあると思います。

一説によると zip するディレクトリの名前は python でなければいけないそうですが、検証はしていません。

ちなみに、自分が利用したバージョンは以下の通りです。

Python 3.8.10 / pip 20.0.2 / fsspec 2022.5.0

zip ファイルを Lambda 関数のレイヤーに追加

「Lambda」 > 「レイヤー」 > 「レイヤーの作成」で、「.zip ファイルをアップロード」します。

「10 MB より大きいファイルの場合は、S3 を利用したアップロードを検討してください」という注意書きがあります。

自分の場合、作成した zip ファイルは 12.5 MB でしたが、気にせずそのままアップロードしました。

お好きな名前で作成してください。オプションはオプションです。

作成したレイヤー画面の右上に ARN があるのでコピーします。

作成したレイヤーを Lambda 関数に追加

Pandas Layer の追加と同様、コンソールから使いたい Lambda 関数の「レイヤーの追加」>「ARN の指定」でコピーした ARN を貼り付けて「検証」->「追加」します。

いざ読み込み

import pandas as pd
csv_file_name = 's3://BUCKET_NAME/OBJECT_KEY'
df = pd.read_csv(csv_file_name)

BUCKET_NAME と OBJECT_KEY で読み込みたいファイルを指定します。

こんな感じで読み込めるはずです。

あとがき

Python や Pandas のバージョンの都合でうまく行ったり行かなかったりするんですかね~