12.6.5 pyqGroupEvalファンクション(オンプレミス・データベース)

このトピックでは、オンプレミスOracle Databaseで使用されるpyqGroupEvalファンクションについて説明します。pyqGroupEvalファンクションは、データを1つ以上の列でグループ化し、各グループに対してユーザー定義Python関数を実行します。

pyqGroupEvalファンクションは、SCR_NAMEパラメータで指定されたユーザー定義Python関数を実行します。INP_NAMパラメータを使用して、データをPython関数に渡します。PAR_LSTパラメータを使用して、引数をPython関数に渡します。GRP_COLパラメータを使用して、1つ以上のグループ化列を指定します。

Python関数は、booleandictfloatintliststrtupleまたはpandas.DataFrameオブジェクトを返すことができます。OUT_FMTパラメータを使用して、返される値の形式を定義します。

構文

pyqGroupEval(
    inp_nam VARCHAR2,
    par_lst VARCHAR2,
    out_fmt VARCHAR2,
    grp_col VARCHAR2,
    scr_name VARCHAR2,
    scr_owner VARCHAR2 DEFAULT NULL)

パラメータ

パラメータ 説明

INP_NAM

SCR_NAMEパラメータで指定されたPython関数に渡すデータを指定する表またはビューの名前。別のユーザーが所有する表またはビューを使用する場合は、<owner name>.<table/view name>という形式を使用します。指定された表またはビューに対する読取りアクセス権が必要です。

PAR_LST

SCR_NAMEパラメータで指定されたユーザー定義Python関数に渡す追加パラメータが含まれるJSON文字列。oml_で始まる特殊な制御引数は、SCR_NAMEで指定された関数に渡されるのではなく、関数の呼出し前後の動作を制御します。

たとえば、入力データ型をpandas.DataFrameとして指定するには、次を使用します。

'{"oml_input_type":"pandas.DataFrame"}'

OUT_FMT

ファンクションによって返される出力の形式。次のいずれかになります。

  • ファンクションによって返された表の列名およびデータ型を指定するJSON文字列。イメージ・データは破棄されます。
  • プロトタイプとして使用する表またはビューの名前。別のユーザーが所有する表またはビューを使用する場合は、<owner name>.<table/view name>という形式を使用します。指定された表またはビューに対する読取りアクセス権が必要です。
  • 文字列'XML'。返される表にXML文字列であるCLOBが含まれることを指定します。XMLには構造化データとイメージの両方が含まれる可能性があり、最初に構造化または半構造化のPythonオブジェクトが含まれ、続いてPython関数によって生成されたイメージが含まれます。
  • 文字列'PNG'。返される表に、Python関数によって生成されたイメージを格納するBLOBが含まれることを指定します。イメージはPNG表示のbase 64エンコーディングとして返されます。
GRP_COL

データのパーティション化に使用するグループ化列の名前。複数の列を区切るには、カンマを使用します。たとえば、GENDERおよびYEARでグループ化する場合:

"GENDER,YEAR"

SCR_NAME

OML4Pyスクリプト・リポジトリ内のユーザー定義Python関数の名前。

SCR_OWNER

登録済Pythonスクリプトの所有者。デフォルト値は「NULL」です。NULLの場合、ユーザーのスクリプト・リポジトリでPythonスクリプトを検索します。

戻り値

ファンクションpyqGroupEvalは、OUT_FMTパラメータ値で指定された構造を持つ表を返します。

例12-18 pyqGroupEvalファンクションの使用

この例では、Python関数create_iris_tableを定義し、create_iris_tableという名前でOML4Pyスクリプト・リポジトリに格納します。次に、pyqEvalを呼び出して、ユーザー定義Python関数を呼び出し、IRISデータベース表を作成します。この例では、パッケージirisPkgを作成し、データ・カーソルの指定でそのパッケージを使用して、ユーザー定義pyqGroupEvalファンクションであるirisGroupEval関数に渡します。別のPython関数group_countを定義し、mygroupcountという名前でスクリプト・リポジトリに格納します。この例では、次に、irisGroupEval関数を呼び出し、mygroupcountという名前で保存されたPython関数に渡します。

PL/SQLブロックで、Python関数create_iris_tableを定義し、create_iris_tableという名前でスクリプト・リポジトリに格納します。

BEGIN
  sys.pyqScriptCreate('create_iris_table',
    'def create_iris_table():
       from sklearn.datasets import load_iris
       import pandas as pd
       iris = load_iris()
       x = pd.DataFrame(iris.data, columns = ["Sepal_Length",\
                        "Sepal_Width","Petal_Length","Petal_Width"])
       y = pd.DataFrame(list(map(lambda x: {0:"setosa", 1: "versicolor",\
                                 2: "virginica"}[x], iris.target)),\
                        columns = ["Species"])
       return pd.concat([y, x], axis=1)');
END;
/

create_iris_tableという名前でスクリプト・リポジトリに格納されているPython関数を使用して、pyqEvalファンクションを呼び出してデータベース表IRISを作成します。

CREATE TABLE IRIS AS
(SELECT * FROM pyqEval(
      NULL,
      '{"Species":"VARCHAR2(10)","Sepal_Length":"number",
        "Sepal_Width":"number","Petal_Length":"number",
        "Petal_Width":"number"}',
      'create_iris_table'
));

Python関数group_countを定義し、mygroupcountという名前でスクリプト・リポジトリに格納します。この関数は、データdatの各グループに対して生成されたpandas.DataFrameを返します。

BEGIN
  sys.pyqScriptCreate('mygroupcount',
    'def group_count(dat):
    import pandas as pd
    return pd.DataFrame([(dat["Species"][0], dat.shape[0])],\
    columns = ["Species", "CNT"]) ');
END;
/

pyqGroupEvalファンクションを呼び出す問合せを発行します。このファンクションのINP_NAM引数では、関数に渡すIRIS表内のデータを指定します。

PAR_LST引数では、特殊な制御引数oml_input_typeを指定します。

OUT_FMT引数では、pyqGroupEvalによって返される表の列名およびデータ型が含まれるJSON文字列を指定します。

GRP_COLパラメータでは、グループ化する列を指定します。

SCR_NAMEパラメータでは、mygroupcountという名前でスクリプト・リポジトリに格納されているユーザー定義Python関数を指定します。

SELECT *
   FROM table(
    pyqGroupEval(
      'IRIS',
      '{"oml_input_type":"pandas.DataFrame"}',
      '{"Species":"varchar2(10)", "CNT":"number"}',     
      'Species',
      'mygroupcount'));

出力は次のようになります。

Species           CNT
---------- ----------
setosa             50
versicolor         50
virginica          50