Snowpark DataFrameをPandas DataFrameに変換し、NumPyの関数を用いてカラムを追加してみた
さがらです。
Snowpark DataFrameをPandas DataFrameに変換し、NumPyの関数を用いてカラムを追加してみる、ということを行ってみたので本記事でまとめてみます。
前置き:Snowpark DataFrameとPandas DataFrameの違いについて
以下の記事からの引用ですが、Snowpark DataFrameとPandas DataFrameについてはこのような違いがあります。
- Snowpark DataFrame
- データ:Snowflakeに保存される(Temporary Tableが作られることもある)
- 処理のタイミング:遅延評価が行われるため、記述したコード1行1行が都度実行されるわけではなく、
show()
などデータの出力が必要となるトリガーがあったタイミングでまとめて実行される(詳細はこちらの公式Docをご覧ください。) - コーディング方法:PandasよりはPySparkに近い
- Pandas DataFrame
- データ:処理の実行環境のメモリに保持される ※SnowparkでPandas DataFrameを使用する場合にはウェアハウスが該当
- 処理のタイミング:記述したコード1行ごとに都度実行される
- コーディング方法:Pandas
Snowpark DataFrameをPandas DataFrameに変換する必要性について
上述の違いを抑えた上で、Snowpark DataFrameをPandas DataFrameに変換する必要性について説明しておきたいと思います。
例えば、PandasとNumPyをがっつり使用した処理を運用をしており、Snowflake上に移行することを考えます。
このとき、一見簡単に移行できるように見えがちですが、下記のようなポイントがあり結構悩ましいです。
- Snowpark DataFrameはPySparkに近い仕様のため、Pandasとかなり異なる
- Snowpark DataFrameとPandas DataFrameのコードの違いについては、下記の記事が非常に参考になります。
- Pandasのよく使われる処理をSnowparkにマッピングしてみた
- PandasとSnowpark for pythonの対応表
- Pandas DataFrame上では、NumPyで出力したndarrayをそのままPandas DataFrameのSeriesに変換して取り込めるが、Snowpark DataFrameではNumPyで出力したndarrayを取り込むことができない
そのため、Snowpark DataFrameをPandas DataFrameに変換した方が既存のコードやノウハウを活かしやすい場面も多いのが現状です。
注意点
上記の通りSnowpark DataFrameをPandas DataFrameに変換したほうが良い場面もありますが、全てのパターンでPandas DataFrameに変換すべきというものではありません。
例えば、DataFrameで扱うデータ量が多いと、Pandas DataFrameはメモリ上にデータを保持するため、メモリ不足によるエラーや処理速度の劣化なども考えられます。
また、遅延評価やSQLに変換して実行されるSnowpark DataFrameの特性を考慮すると、全く同じデータ量に対して同じウェアハウスで同じ処理を行った場合の処理速度はSnowpark DataFrameのほうが速いことが多いと思います。
このように、すべてのユースケースでSnowpark DataFrameをPandas DataFrameに変換すべきではないため、ご注意ください。
やってみた
ということで、早速Snowpark DataFrameをPandas DataFrameに変換し、NumPyの関数を用いてカラムを追加してみようと思います。
検証環境
- コーディング環境:Python Worksheet
- ウェアハウス:サイズXS、クラスター数1
Python Worksheetで記述してみる
早速実際のコードになりますが、下記のコードをPython Worksheetに記述しました。
Python Worksheetを立ち上げたときに表示されるPythonコードに少しだけ追記したコードとなります。
import snowflake.snowpark as snowpark from snowflake.snowpark.functions import col import numpy as np import pandas as pd def main(session: snowpark.Session): # information_schemaのpackagesビューで、language列が"python"のレコードのみ、Snowpark DataFrameとしてロード tableName = 'information_schema.packages' snowdf = session.table(tableName).filter(col("language") == 'python') # PandasのDataFrameに変換 pandadf = snowdf.to_pandas() # Snowpark DataFrameではエラーとなるnumpy.whereを用いた列追加を行う。※snowparkの場合には、snowflake.snowpark.functions.whenでも可能な処理ですがブログ用の検証なのでご了承ください… pandadf["VERSION_FLG_PANDAS"] = np.where(pandadf["VERSION"] == "1.3.0", 1, 0) # Pandas DataFrameからSnowpark DataFrameに変換 returndf = session.create_dataframe(pandadf) # Snowpark DataFrameの内容をテーブルとして出力 returndf.write.mode("overwrite").save_as_table("python_stored_test_tbl") return returndf
ポイントとしては、以下になります。
to_pandas()
を使うことで、Snowpark DaraFrameをPandas DataFrameに変換できる- Pandas DataFrameに変換したら、NumPyの処理を記述しPandas DataFrameにカラムを追加
session.create_dataframe()
を使うことで、引数に入れたPandas DataFrameをSnowpark DataFrameに変換する
ストアドプロシージャとしてデプロイする
また、PandasやNumPyを使用している場合でも問題なくPython Worksheet からストアドプロシージャとして開発した処理をデプロイ可能です。
デプロイしたら、あとはcall
すればすぐに使用できます。
最後に
簡単ではありますが、Snowpark DataFrameをPandas DataFrameに変換し、NumPyの関数を用いてカラムを追加してみる、ということを行ってみました。
データ量が多い場合などはSnowpark DataFrameとして処理を行ったほうが望ましいと思いますが、コード1行でPandas DataFrameへの変換もできるため、「Snowpark上で既存のPandasの処理をサクッと動かしてみたい」「データを絞り込んでワンポイントでPandas及び関連ライブラリを活用したい」みたいな場面では役立つと思います。