見出し画像

Snowflakeさわってみた。Python UDFs(ユーザー定義関数)試してみた。

分析屋の下滝です。

Snowflakeさわってみよう、三回目です。今回は、何となく気になった、UDFs(ユーザー定義関数)という機能を試してみます。

いくつかの言語(SQL、JavaScript、Java、Python)で関数を定義できますが、今回は python で書いてみます。

UDFs(ユーザー定義関数)

公式ドキュメントのとおりですが、次のように呼び出して使える関数を作ってみます。引数で渡された整数に対して1を追加するだけの関数です。

select addone(10);

出力結果は、以下となります。

11

関数を作るコードはこれです。公式のものそのままです。

create or replace function addone(i int)
returns int
language python
runtime_version = '3.8'
handler = 'addone_py'
as
$$
def addone_py(i):
  return i + 1
$$;

では、Web画面上でこの関数を定義してみます。ワークシートを選択するか作成します。

上記のコードをコピペし、貼り付けて、実行します。データベースを選択しておく必要があります。

左のメニューで、関数に新しく関数が追加されていることがわかります。

作成した関数を実行してみます。

select addone(10);

11という結果が得られました。

実際には、テーブルのデータを処理することが多いと思いますので、次のようなテーブルでのデータに対して、関数を適用してみます。

PRICEカラムの各行に対して、関数を適用します。

select name, addone(price) from PRODUCT;

出力は次のようになります。PRICEにそれぞれ1が追加されています。

以上です。

UDFsでは、他にも異なる処理の方法が提供されています。
・バッチAPI
・ユーザー定義テーブル関数(UDTFs)

バッチAPIは、入力行のバッチを Pandas DataFramesとして受け取り、結果のバッチを Pandas配列またはシリーズとして返すPython関数を定義できるというものです。

ユーザー定義テーブル関数(UDTFs)は、表形式の結果を返すことができます。テーブル関数は、入力行ごとに行のセットを返します。返されるセットには、0行、1行、またはそれ以上の行を含めることができます。各行には、1つ以上の列を含めることができます。

バッチAPIに関しては次回以降で見てみます。

以下では、ユーザー定義テーブル関数に関して見てみます。

ユーザー定義テーブル関数(UDTFs)

関数を定義します。

create or replace function double_price(price int)
returns table (price1 int, price2 int)
language python
runtime_version=3.8
handler='DoublePrice'
as $$
class DoublePrice:
    def process(self, price):
        yield (price, price * 2)
$$;

process メソッドは、各入力行を処理し、表形式の値をタプルとして返します。ここでは、受け取った引数と、引数を倍にしたものを2つ返しています。

まずは、単に関数を呼び出してみます。tableキーワードで関数をラップする必要があります。

select * from table(double_price(1));

結果は、次のようになります。

次に、テーブルと組み合わせて呼び出してみます。

select * from Product, table(double_price(price));

結果は、次のようになります。

次に、複数の行を返すようなテーブル関数を定義してみます。

create or replace function double_price2(price int)
returns table (price1 int, price2 int)
language python
runtime_version=3.8
handler='DoublePrice'
as $$
class DoublePrice:
    def process(self, price):
        yield (price, price * 2)
        yield (price * 3, price *4)
$$;

yieldが一つ増えました。これで2行分を返すことになります。

select * from table(double_price2(1))

結果は、次のようになります。

次に、テーブルと組み合わせて呼び出してみます。

select * from PRODUCT, table(double_price2(1)) order by id

結果は、次のようになります。

各行に対して、2行分が出力されています。

今回は以上です。

Pythonでのテーブル関数のその他の詳しい仕様は、公式ドキュメントを参照してください。

株式会社分析屋について

ホームページはこちら。

noteでの会社紹介記事はこちら。

【データ分析で日本を豊かに】
分析屋はシステム分野・ライフサイエンス分野・マーケティング分野の知見を生かし、多種多様な分野の企業様のデータ分析のご支援をさせていただいております。 「あなたの問題解決をする」をモットーに、お客様の抱える課題にあわせた解析・分析手法を用いて、問題解決へのお手伝いをいたします!
【マーケティング】
マーケティング戦略上の目的に向けて、各種のデータ統合及び加工ならびにPDCAサイクル運用全般を支援や高度なデータ分析技術により複雑な課題解決に向けての分析サービスを提供いたします。
【システム】
アプリケーション開発やデータベース構築、WEBサイト構築、運用保守業務などお客様の問題やご要望に沿ってご支援いたします。
【ライフサイエンス】
機械学習や各種アルゴリズムなどの解析アルゴリズム開発サービスを提供いたします。過去には医療系のバイタルデータを扱った解析が主でしたが、今後はそれらで培った経験・技術を工業など他の分野の企業様の問題解決にも役立てていく方針です。
【SES】
SESサービスも行っております。