このトピックでは、PyODPS DataFrame のカスタム関数で pandas、scipy、scikit-learn などのサードパーティパッケージをアップロードして使用する方法について説明します。
PyODPS DataFrame は、MaxCompute データを操作する pandas に似た API を提供します。また、pandas とデータベースを使用してローカルで実行することもできます。
PyODPS DataFrame は、map や apply などの pandas に似たメソッドに加えて、MapReduce API を提供し、大規模データ処理向けに pandas の構文を拡張します。
PyODPS のカスタム関数は、MaxCompute 上で実行するためにシリアル化されます。デフォルトの MaxCompute Python 環境には numpy のみが含まれますが、現在は pandas、scipy、scikit-learn などの C 拡張を含むライブラリをカスタム関数で使用できます。
PyODPS 0.7.4 以降が必要です。
サードパーティパッケージのアップロード
サードパーティパッケージのアップロードは 1 回だけで済みます。パッケージがすでに MaxCompute リソースとして使用可能な場合、この手順は省略できます。
主要な Python パッケージの多くは wheel (.whl) ファイルとして提供されており、さまざまなプラットフォーム向けに事前ビルドされたバイナリが含まれています。まず、MaxCompute ランタイムと互換性のあるパッケージを見つけます。
MaxCompute でカスタム関数を実行するには、すべての依存関係パッケージを含める必要があります。各パッケージの依存関係は、次の表に記載されています。
パッケージ名 | 依存関係 |
pandas | numpy、python-dateutil、pytz、six |
scipy | numpy |
scikit-learn | numpy, scipy |
numpy パッケージは事前にインストールされています。そのため、pandas、scipy、scikit-learn を使用するには、python-dateutil、pytz、pandas、scipy、sklearn、six のみをアップロードすればよいです。
python-dateutil にアクセスし、python-dateutil-2.6.0.zip を見つけてダウンロードします。
ファイル名を python-dateutil.zip に変更し、MaxCompute コンソールを使用してリソースとしてアップロードします。
add archive python-dateutil.zip;同様の手順で pytz と six をアップロードします。pytz-2017.2.zip と six-1.11.0.tar.gz を見つけてダウンロードし、アップロードします。
pandas などの C 拡張を含むパッケージの場合は、ファイル名に cp27-cp27m-manylinux1_x86_64 を含む wheel ファイルを見つける必要があります。これにより、MaxCompute 上でパッケージが正しく実行されることが保証されます。pandas-0.20.2-cp27-cp27m-manylinux1_x86_64.whl を見つけてダウンロードし、拡張子を .zip に変更してから、MaxCompute コンソールで add archive pandas.zip; コマンドを実行してアップロードします。
他のパッケージについても同様の手順に従います。必要なリソースを次の表に示します。
パッケージ名 | ファイル名 | アップロードしたリソース名 |
python-dateutil | python-dateutil.zip | |
pytz | pytz.zip | |
six | six.tar.gz | |
pandas | pandas.zip | |
scipy | scipy.zip | |
scikit-learn | sklearn.zip |
代替手段として、PyODPS のリソースアップロード API を使用してリソースをアップロードすることもできます。これも 1 回限りの操作です。
コードの検証
すべてのライブラリを使用する簡単な関数を作成します。ベストプラクティスとして、これらのサードパーティパッケージは関数内で import することが推奨されます。
def test(x): from sklearn import datasets, svm from scipy import misc import numpy as np iris = datasets.load_iris() assert iris.data.shape == (150, 4) assert np.array_equal(np.unique(iris.target), [0, 1, 2]) clf = svm.LinearSVC() clf.fit(iris.data, iris.target) pred = clf.predict([[5.0, 3.6, 1.3, 0.25]]) assert pred[0] == 0 assert misc.face().shape is not None return x説明上記のコードはデモ目的のみです。このトピックで言及したすべてのパッケージを使用することを目的としています。
関数を定義したら、簡単な map 操作を記述します。
説明ランタイムでアイソレーションが有効になっていることを確認してください。プロジェクトレベルで有効になっていない場合は、グローバルオプションを設定して現在のセッションで有効にできます。
from odps import options options.sql.settings = {'odps.isolation.session.enable': True}execute メソッドで指定することで、特定の実行に対してアイソレーションを有効にすることもできます。
同様に、options.df.libraries を使用して必要なパッケージをグローバルに指定するか、実行時に指定できます。依存関係パッケージを含め、すべてのパッケージを指定する必要があります。
定義した関数を呼び出します。
hints = { 'odps.isolation.session.enable': True } libraries = ['python-dateutil.zip', 'pytz.zip', 'six.tar.gz', 'pandas.zip', 'scipy.zip', 'sklearn.zip'] iris = o.get_table('pyodps_iris').to_df() print iris[:1].sepal_length.map(test).execute(hints=hints, libraries=libraries)
まとめ
サードパーティパッケージとその依存関係がすでにアップロードされている場合は、コード内で直接指定できます。アップロードされていない場合は、このトピックで説明したとおり、先にパッケージをアップロードする必要があります。
PyODPS リソース
詳細については、「PyODPS ユーザーガイド」をご参照ください。
関連するコードサンプルについては、GitHub の aliyun-odps-python-sdk をご参照ください。