2022年10月にリリースされたTableau 2022.3ですが、
その中に「テーブル拡張機能(Tableau公式サイト上では表拡張機能)」なる機能が追加されていました。
(Tableau公式サイトURL:https://www.tableau.com/ja-jp/2022-3-features)
内容をみるとPythonやR等と連携して処理結果を他のデータソースと同じように、
テーブルとしてTableauで取り込める機能なのですが、
いざ試してみようと思ったら、どうやって記述すればいいのかで躓いてしまったので、
備忘としてこのテーブル拡張機能を使えるようになるまでの手順を残しておこうと思います。
今回はPythonとの連携を行います。
テーブル拡張機能はPython、Einstein Discovery、Rと連携する分析拡張機能を用いた機能です。
入力をテーブルで渡し、処理スクリプトの結果をTableau側へ出力します。
これまで分析拡張機能では、計算フィールドを介して処理スクリプトを実行し計算結果を1つのフィールド値としてTableau側に出力することができましたが、
このテーブル拡張機能を使うとテーブル自体をTableau側に渡すことができ、入力と違う結果も出力することができるようになります。
OS:Windows10
Python:3.9.6
Tableau Desktop:2022.3.0
まずはPython側でTableauからの入力を受け取れるようにするため、TabPyをインストールします。
オンラインの環境であれば以下でインストールができます。
pip install tabpy |
インストールができたらコンソールにTabPyと入力してTabPy Serverを起動します。
起動できると9004番ポートで受け付けしますとログに表示されます。
Tableau Desktopからこのポートを指定することでデータをPython側の処理へ渡すことができるようになります。
(tabpy_venv) C:\Users\n-sato\Documents\VScode\tabpy_try: tabpy |
2022-11-23,19:40:11 [INFO] (app.py:app:244): Parsing config file c:\users\n-sato\documents\vscode\tabpy_try\tabpy\lib\site-packages\tabpy\tabpy_server\app\..\common\default.conf |
2022-11-23,19:40:11 [INFO] (app.py:app:436): Loading state from state file C:\Users\n-sato\Documents\VScode\tabpy_try\tabpy\Lib\site-packages\tabpy\tabpy_server\state.ini |
2022-11-23,19:40:11 [INFO] (app.py:app:332): Password file is not specified: Authentication is not enabled |
2022-11-23,19:40:11 [INFO] (app.py:app:347): Call context logging is disabled |
2022-11-23,19:40:11 [INFO] (app.py:app:125): Initializing TabPy... |
2022-11-23,19:40:11 [INFO] (callbacks.py:callbacks:43): Initializing TabPy Server... |
2022-11-23,19:40:11 [INFO] (app.py:app:129): Done initializing TabPy. |
2022-11-23,19:40:11 [INFO] (app.py:app:83): Setting max request size to 104857600 bytes |
2022-11-23,19:40:11 [INFO] (callbacks.py:callbacks:64): Initializing models... |
2022-11-23,19:40:11 [INFO] (app.py:app:106): Web service listening on port 9004 |
上部のメニューのヘルプ > 設定とパフォーマンス > 分析拡張機能接続の管理 を選択

TabPy を選択

ローカルホストを指定し、ポート番号は9004を設定。

テスト接続を押下して正常に接続ができましたと表示されることを確認。

保存を押下し、閉じるでウィンドウを閉じます。
これで連携の準備ができました。
データに接続していきます。ここではサンプルスーパーストアのデータを利用します。
あまり説明する必要ないかもしれませんが、念のため接続手順も書いておきます。
スタート画面から ファイルへの欄にある「Microsoft Excel」を選択します。

サンプル – スーパーストア.xlsを選択します。

データソース画面に遷移します。
通常ならこのままシート欄にある「注文」をキャンバスに配置してワークシートに遷移するところですが、テーブル拡張機能を利用するにはここで「新しいテーブル拡張機能」をキャンバスに配置します。

キャンバスにドロップすると入力データを配置する部分(「ここにシートをドラッグ」と書かれている部分)と、その横にスクリプトを記載する部分がある画面構成になります。
ここで「注文」を入力データとして配置します。

「注文」シートを配置した状態です。
画面下部のデータグリッドの入力テーブルに「注文」のデータが表示されるようになりました。

Python側で行う処理はスクリプト欄に記述します。
補足ですが、あらかじめ計算処理を関数化しておきたい場合、別途TabPy ClientをPython側でインストールし、TabPy Clientを使って関数をTabPy Serverにデプロイすることで実現できます。
今回は動作確認目的なので、TabPy Clientは用いずにスクリプト欄に処理を記載していきたいと思います。
「製品 ID」のカラムを‐(ハイフン)で分割した結果を追加して返すスクリプトを作成します。
書き方は普通のPythonスクリプトを記載する感覚で行けますが、最後にreturnを記載する必要があります。
後ほどスクリプトでどんな処理を行っているか解説します。
import pandas as pd |
df = pd.DataFrame(_arg1) |
df_2 = df["製品 ID"].str.split('-', expand=True) |
df_2.rename(columns={0: '製品ID_大分類', 1: '製品ID_中分類', 2: '製品ID_No'}, inplace=True) |
df_3 = pd.concat([df, df_2], axis=1) |
return df_3.to_dict(orient='list') |
上記をスクリプト欄に記載の上、「適用」ボタンを押下すると出力テーブルに
スクリプト実行結果が出力されています。
「製品 ID」のカラムを‐(ハイフン)で分割した結果のカラム(「製品ID_大分類」、「製品ID_中分類」、「製品ID_No」)も追加できることが確認できました。
※仕様詳細は未調査ですが、カラムの順番はTableauで自動的にソートされた順番となるようです。

Pythonスクリプトの解説です。
import pandas as pd |
pandasのインポートを行っています。
df = pd.DataFrame(_arg1) |
入力データをDataFrame形式で読み込んでいます。
テーブル拡張機能における入力データは「_arg1」という名称でマッピングされているので、入力データを取得する際は「_arg1」と記載します。
※入力データの指定方法はこちらを参考にしております。
df_2 = df["製品 ID"].str.split('-', expand=True) |
df_2.rename(columns={0: '製品ID_大分類', 1: '製品ID_中分類', 2: '製品ID_No'}, inplace=True) |
df_3 = pd.concat([df, df_2], axis=1) |
データ加工処理です。
「製品 ID」のカラムを‐(ハイフン)で分割した結果を作成したのち、元のデータに追加する処理を行っています。
return df_3.to_dict(orient='list') |
処理結果をTableau側に渡しています。
渡し方はdict(辞書)形式、「orient=’list’」でvalue内は値のみにして渡します。
つけない場合:value内は「行ラベル:値」の情報になります。
{'オーダー ID': {0: 'JP-2021-1000099', 1: 'JP-2022-1001016', 2: 'JP-2020-1001113', … } |
つける場合:value内は「値」のみの情報になります。
{'オーダー ID': ['JP-2021-1000099', 'JP-2022-1001016', 'JP-2020-1001113', … } |
これでデータの加工は終わりです。あとは通常通りにワークシートへ遷移してビューの作成を行うことができます。
ワークシートに遷移すると、左のペインに3つのフィールドが追加されているのも確認できます。

結論としては、可能かと思われます。
入力データは何もない状態で、以下のテストスクリプトを組みました。
import pandas as pd |
df = pd.DataFrame({'col1': [1, 2, 3], 'col2': ['AAA', 'BBB', 'CCC']}) |
return df.to_dict(orient='list') |
適用を押下すると、スクリプトで定義した値が出力できています。

Pythonスクリプト側で直接CSVファイルを指定して読み込みもできました。
テーブル拡張機能だけでデータソースを準備することもできそうです。
import pandas as pd |
df = df = pd.read_csv('C:/data/sample_superstore.csv', encoding='utf8') |
return df.to_dict(orient='list') |

今回はテーブル拡張機能をもちいたTableauとPythonの連携について、連携手順を紹介させていただきました。
テーブル自体をTableauに渡すことが可能なため、計算フィールドでの連携方法より自由度が高くなった印象があります。
スクリプトの書き方はreturn部分の書き方に気を付ければ普通にPythonスクリプトを書く感じでいけるのかなと思います。
テーブル拡張機能使ってみたいけどわからないって方向けの導入手順として活用いただけたら嬉しいです。
最後までお読みいただきありがとうございました。