Dragon Arrow written by Tatsuya Nakaji, all rights reserved animated-dragon-image-0164

GCSを直接データフレームで操作

Feb 12, 2020

pythonからGCSを直接操作


概要


GCSに大きなデータをアップしておき、そのデータをダウンロードすることなく操作したいことは機械学習をやっていると起こる。

機械学習コンペでは時に500GB以上のデータをダウンロードしなければならない。

そこで、一度GCSに保存されたデータをダウンロードせずにpythonで直接読み込み、機械学習を行うための手法を紹介する。


手順


1. ライブラリのインストール


(Anacondaでのインストール)

$ conda install -c conda-forge google-cloud-storage

(pipでのインストール)

$ pip install google-cloud-storage


2. pythonで読み込む


パターンA. ファイル名で読み込む

from google.cloud import storage as gcs
import pandas as pd
from io import BytesIO


bucket_name = "your_bucket"
fname = "storage_file_path"
project_name = "your_project_name"


#プロジェクト名を指定してclientを作成
client = gcs.Client(project_name)
#バケット名を指定してbucketを取得
bucket = client.get_bucket(bucket_name)
#Blobを作成
blob = gcs.Blob(fname, bucket)
content = blob.download_as_string()
train = pd.read_csv(BytesIO(content))
train.head()


特定のファイルを読み込む場合、これで問題ありません。しかし、パターン一致で検索して読み込みたい場合、google-cloud-storageでは実現できません。そこで、pythonコードで工夫し、それを実現します。

以下の手法を紹介。




パターンB. パターンマッチのファイルを読み込む

from google.cloud import storage as gcs
import pandas as pd
from io import BytesIO


bucket_name = "your_bucket"
# fname = "storage_file_path"
project_name = "your_project_name"


client = gcs.Client(project_name)
bucket = client.get_bucket(bucket_name)


train = []
for blob in bucket.list_blobs():
    if fnmatch.fnmatch(blob.name, "*.json"):
        # print(blob)
        content = blob.download_as_string()
        tmp = pd.read_json(BytesIO(content))
        train.append(tmp)

train = pd.concat([d for d in train])
train.head()
          owxbbpjpch.mp4 vpmyeepbep.mp4  ... wadgdooqpl.mp4 wwwbocaabd.mp4
label               FAKE           REAL  ...            NaN            NaN
split              train          train  ...            NaN            NaN
original  wynotylpnm.mp4            NaN  ...            NaN            NaN
label                NaN            NaN  ...            NaN            NaN
split                NaN            NaN  ...            NaN            NaN


[5 rows x 109127 columns]


ここで注目するのは、bucket.list_blobs()で全ファイルを読み込み、pythonのfnmatchで篩(ふるい)に掛けるという仕様です。

一旦全ファイルを読み込むのは効率的ではないですが、google-cloud-storageがパターン検索に対応するまでは、現状この手法が良さそうです。