CP4DのModelerFlowでPython拡張ノードを実行する

CP4DのModelerFlowでPythonの拡張ノードを実行してみます。

* テスト環境
    * CP4D 4.5.2

* テストストリーム

https://github.com/hkwd/220201watsonstudio/raw/master/221020pythonextension/python%E6%8B%A1%E5%BC%B5%E3%83%8E%E3%83%BC%E3%83%89%E5%9F%BA%E6%9C%AC.str

# 拡張ノードの実行
次のようなユーザー入力を用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/312e7520-ecac-66ea-51a6-87018d10127b.png)

次のような6行のデータが入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/946061c4-b249-85ee-cc27-9f00e5f58dd3.png)

「拡張変換」ノードで、スクリプトタイプで「Spark用Python」を選び以下のようなPythonスクリプトを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/715bfd21-668b-7d6c-bc4a-9f570a861301.png)

sparkSQLをつかってC1=1のデータだけを抽出しています。

```python:拡張変換
import sys
print("sys.version:",sys.version)
import pyspark
print("pyspark version:",pyspark.__version__)
import spss.pyspark.runtime
asc = spss.pyspark.runtime.getContext()
if asc.isComputeDataModelOnly():
    sc = asc.getSparkInputSchema()
    asc.setSparkOutputSchema(sc) 
else:
    df = asc.getSparkInputData()
    sqlContext = asc.getSparkSQLContext()
    df.createOrReplaceTempView("t1")  
    out1 = sqlContext.sql("select * from t1 where C1=1") 
    asc.setSparkOutputData(out1)    
```

「テーブル」ノードを接続して実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/5a390026-4177-943e-aef7-90e022d8ace3.png)

C=1のデータだけが抽出できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/bca96732-1efc-90a0-6d5d-36f341edc7be.png)


拡張変換ノードの「コンソール出力」に利用しているPythonとpysparkのバージョンを出力したので、確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d94624f5-6d3d-72f2-0204-b1c0ea2c0ba0.png)

Python: 3.8.6
pyspark: 3.2.1
が使われていました。


# パッケージを導入する

パッケージが足りない場合はエラーになります。デフォルト環境にはpandasやnumpyが入っていません。ですのでimport pandasで以下のようなエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/59eb8039-41c5-5421-041e-2cd33ae8cfa5.png)
in <module> import pandas as pd ModuleNotFoundError: No module named 'pandas'

その場合、以下のコマンドで導入することができます。

```python:import pandas
import sys
import subprocess
subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pandas', '--quiet', '--no-input'])
import pandas as pd
```
例えば以下の記事のストリームの拡張変換ノードはpandasを使っています。
SPSS Modelerで正規表現を使う（Python拡張ノード版） - Qiita 

https://qiita.com/kawada2017/items/c0480bc2b3dcc9cd7be6

以下のように導入のスクリプトを入れることで動作します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b520b5a8-b8c2-2aea-58c2-76ab666b544f.png)

# グラフ表示の制限

テストをしたCP4D 4.5.2ではグラフ表示はできませんでした。以下の記事のスクリプトを実行したところ、エラーにはなりませんが、何も表示されませんでした。

SPSS Modelerの拡張ノードでPythonを利用する ①セットアップと可視化 - Qiita 

https://qiita.com/1000aki/items/72c3c9ea0fe00edd6d19


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1d478aba-a2a1-994c-b6a6-61a5f87f3aa2.png)

上の記事でも紹介されている以下のリクエストと関連していますので、グラフ表示が欲しい場合には投票をしていただくとよいと思います。

Extension Output Node for Python with Graph Output tab like R

https://ibm-data-and-ai.ideas.aha.io/ideas/MDLR-I-329

#### 参考：拡張ノード - IBM Documentation 

https://www.ibm.com/docs/ja/cloud-paks/cp-data/4.0?topic=palette-extension-nodes