Snowpark DataFrameをPandas DataFrameに変換し、NumPyの関数を用いてカラムを追加してみた

2023.11.27

さがらです。

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を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及び関連ライブラリを活用したい」みたいな場面では役立つと思います。