はじめに
データアナリティクス事業本部のkobayashiです。
BigQueryのエンジンを利用してPandas互換のDataframeやscikit-learnライクな機械学習ライブラリを扱えるBigQuery DataFramesを使ってみたのでまとめます。
BigQuery DataFramesとは
BigQuery DataFramesは、DataFrameとしてはpandas互換のPythonic DataFrameのbigframes.pandas
モジュールとscikit-learnライクのbigframes.ml
モジュールを扱うことができ、それらの機能をBigQueryエンジンで実行することができます。
詳しくは以下をご確認ください。
BigQuery DataFramesを使ってみる
では早速BigQuery DataFramesを使ってみたいと思います。試すこととしてはまずはpandas互換のPythonic DataFrameのbigframes.pandas
モジュールで一般的にPandasで行うデータ分析を行ってみます。
scikit-learnライクのbigframes.ml
モジュールに関しては別エントリでまとめたいと思います。
環境
- Python: 3.11.4
- bigframes: 0.3.0
インストール
インストールはいつも通りpipで簡単に済ませます。
$ pip install bigframes
BigQuery DataFramesを使ってみる
BigQuery DataFramesの準備が整ったので早速試してみたいと思います。
扱うデータは以下のような天候データを扱います。
SELECT * FROM {project_id}.data_set_test.jp_weather;
date | month | city | w_type | temperature | precipitation | sunlight | cloudage |
---|---|---|---|---|---|---|---|
2021-11-13 | 11 | 京都 | 晴 | 10.500000000 | 0.000000000 | 7.600000000 | null |
2021-03-03 | 3 | 京都 | 晴 | 5.900000000 | 0.000000000 | 6.600000000 | null |
2021-11-14 | 11 | 京都 | 晴 | 12.100000000 | 0.000000000 | 3.600000000 | null |
2021-03-04 | 3 | 京都 | 晴 | 10.000000000 | 0.000000000 | 6.100000000 | null |
2021-11-15 | 11 | 京都 | 晴 | 12.800000000 | 0.000000000 | 7.900000000 | null |
2021-11-16 | 11 | 京都 | 晴 | 13.500000000 | 0.000000000 | 7.600000000 | null |
2021-11-17 | 11 | 京都 | 晴 | 12.800000000 | 0.000000000 | 8.000000000 | null |
2021-03-07 | 3 | 京都 | 晴 | 8.200000000 | 0.000000000 | 6.100000000 | null |
このデータをBigQuery DataFramesで扱います。内容としては{project_id}.data_set_test.jp_weather
のデータを使ってPandasで行う一般的な分析操作を行います。コードは以下になります。
import os
import bigframes.pandas as bpd
bpd.options.bigquery.project = os.environ.get("GOOGLE_PROJECT_ID")
bpd.options.bigquery.location = "asia-northeast1"
df1 = bpd.read_gbq("{project_id}.data_set_test.jp_weather")
# df1 = bpd.read_gbq("SELECT * FROM {project_id}.data_set_test.jp_weather")
# データの要約
## 最初の5行を取得
print(df1.head())
## 最後の5行を取得
print(df1.tail())
## 行数・列数を取得
print(df1.shape)
## 列名の取得
print(df1.columns)
## 列のデータ型を取得
print(df1.dtypes)
## 要約統計量
print(df1.describe())
# データの加工
## 列の抽出
print(df1["date"])
print(df1[["date", "temperature"]])
## cityごとのデータ数
print(df1["city"].value_counts())
# データの集計
print(df1.groupby("city")["temperature"].mean().sort_values(ascending=False))
使い方として主な箇所は1行目から7行目になります。
- 2行目:
import bigframes.pandas as bpd
でbigframes.pandas
モジュールをインポートする - 4行目:
bpd.options.bigquery.project
にGoogleCloudのプロジェクトIDを設定する - 5行目:
bpd.options.bigquery.location
でデータセットのロケーションを設定する。設定しない場合はデフォルトのUS
ロケーションが使われる。 - 7行目:
bpd.read_gbq()
でデータを読み込む。引数には上記のコードの様にテーブルIDを指定する方法とSQLを指定する方法が可能。
9行明以降はPandasで扱える処理をbigframes.pandas
モジュールでも使ってみます。結果は以下のように通常のpandasと同様の結果が返ってきますのでPandasでのデータ分析を普段から行っているなら特に違和感なく使えるかと思います。
# データの要約
## 最初の5行を取得
date month city ... precipitation sunlight cloudage
0 2021-11-13 11 京都 ... 0E-9 7.600000000 None
1 2021-03-03 3 京都 ... 0E-9 6.600000000 None
2 2021-11-14 11 京都 ... 0E-9 3.600000000 None
3 2021-03-04 3 京都 ... 0E-9 6.100000000 None
4 2021-11-15 11 京都 ... 0E-9 7.900000000 None
[5 rows x 8 columns]
## 最後の5行を取得
date month city ... precipitation sunlight cloudage
3655 2021-04-14 4 名古屋 ... 2.500000000 6.000000000 5.800000000
3656 2021-04-22 4 名古屋 ... 0E-9 11.500000000 5.800000000
3657 2022-01-16 1 名古屋 ... 0E-9 9.000000000 5.800000000
3658 2021-07-30 7 名古屋 ... 2.000000000 8.200000000 5.800000000
3659 2021-11-10 11 名古屋 ... 0E-9 4.200000000 5.800000000
[5 rows x 8 columns]
## 行数・列数を取得
(3660, 8)
## 列名の取得
Index(['date', 'month', 'city', 'w_type', 'temperature', 'precipitation',
'sunlight', 'cloudage'],
dtype='object')
## 列のデータ型を取得
date date32[day][pyarrow]
month Int64
city string[pyarrow]
w_type string[pyarrow]
temperature object
precipitation object
sunlight object
cloudage object
dtype: object
## 要約統計量
date month
count 3660 3660.0
mean 2021-08-21 12:00:00 6.513661
min 2021-02-20 00:00:00 1.0
25% 2021-05-22 00:00:00 4.0
50% 2021-08-21 12:00:00 7.0
75% 2021-11-21 00:00:00 10.0
max 2022-02-20 00:00:00 12.0
std NaN 3.451705
## 列の抽出
0 2021-11-13
1 2021-03-03
2 2021-11-14
3 2021-03-04
4 2021-11-15
...
3655 2021-04-14
3656 2021-04-22
3657 2022-01-16
3658 2021-07-30
3659 2021-11-10
Name: date, Length: 3660, dtype: datetime64[s]
## 列の抽出
date temperature
0 2021-11-13 10.500000000
1 2021-03-03 5.900000000
2 2021-11-14 12.100000000
3 2021-03-04 10.000000000
4 2021-11-15 12.800000000
... ... ...
3655 2021-04-14 16.100000000
3656 2021-04-22 19.900000000
3657 2022-01-16 4.300000000
3658 2021-07-30 29.100000000
3659 2021-11-10 13.300000000
[3660 rows x 2 columns]
## cityごとのデータ数
city
京都 366
仙台 366
大阪 366
札幌 366
東京 366
横浜 366
福岡 366
那覇 366
長野 366
名古屋 366
Name: count, dtype: int64[pyarrow]
date month city ... precipitation sunlight cloudage
0 2021-11-13 11 京都 ... 0E-9 7.600000000 None
1 2021-03-03 3 京都 ... 0E-9 6.600000000 None
2 2021-11-14 11 京都 ... 0E-9 3.600000000 None
3 2021-03-04 3 京都 ... 0E-9 6.100000000 None
4 2021-11-15 11 京都 ... 0E-9 7.900000000 None
... ... ... ... ... ... ... ...
3655 2021-04-14 4 名古屋 ... 2.500000000 6.000000000 5.800000000
3656 2021-04-22 4 名古屋 ... 0E-9 11.500000000 5.800000000
3657 2022-01-16 1 名古屋 ... 0E-9 9.000000000 5.800000000
3658 2021-07-30 7 名古屋 ... 2.000000000 8.200000000 5.800000000
3659 2021-11-10 11 名古屋 ... 0E-9 4.200000000 5.800000000
[3660 rows x 8 columns]
# データの集計
city
那覇 23.688798
福岡 18.062022
大阪 17.378142
横浜 16.779235
京都 16.674044
名古屋 16.671038
東京 16.418579
仙台 13.662295
長野 12.698361
札幌 10.26694
Name: temperature, dtype: object
データのメモリ展開
上記のコードですが、BigQuery DataFramesの特性上、BigQuery サービス上でデータと処理を保持をされています。したがってdf1
を使って操作を行うたびにBigQueryのセッションからデータを取得しています。代わりに
df1 = bpd.read_gbq("{project_id}.data_set_test.jp_weather").to_pandas()
のようにするとこの時点でデータをメモリ上に読み込んでから後続の処理をするようになります。この場合はdf1
の操作のたびにBigQueryのAPIを呼び出すことはしなくなしますが、実行マシーンのメモリを圧迫するのでケースバイケースでの使い分けが必要になります。
まとめ
BigQueryのエンジンを利用してPandas互換のDataframeを扱えるBigQuery DataFramesを使ってみました。bigframes.pandas.read_gbq()
でBigQuery上のデータを読み込んでしまえば以降はPandasと同じ関数を使って分析を行うことができ非常に便利です。
次回、scikit-learnライクのbigframes.ml
モジュールを扱ってみたいと思います。
最後まで読んで頂いてありがとうございました。