MaxComputeで使用されるPython 2のバージョンは、Python 2.7です。 このトピックでは、Python 2でユーザー定義集計関数 (UDAF) を記述する方法について説明します。
UDAFコード構造
MaxCompute Studioを使用して、Python 2でUDAFコードを記述できます。 UDAFコードには次の情報を含めることができます。
エンコーディング宣言: オプション。
宣言形式は、
#coding: utf-8または# -*- coding: utf-8 -*-です。 2つの形式は同等です。 Python 2で記述されたUDAFコードに漢字が表示される場合、UDAFを実行するとエラーが返されます。 この問題に対処するには、コードのヘッダーにエンコード宣言を追加する必要があります。モジュールのインポート: 必須。
UDAFコードには、少なくとも
from odps.udf import annotateとfrom odps.udf import BaseUDAFを含める必要があります。from odps.udf import annotateは、関数署名モジュールをインポートするために使用されます。 これにより、MaxComputeはコードで定義されている関数シグネチャを識別できます。from odps.udf import BaseUDAFはPython UDAFの基本クラスです。 このクラスを使用して、iterate、merge、terminateなどのメソッドを派生クラスに実装する必要があります。UDAFコードでファイルまたはテーブルリソースを参照する場合は、UDAFコードに
from odps.distcache import get_cache_fileまたはfrom odps.distcache import get_cache_tableを含める必要があります。関数署名: 必須。
関数シグネチャは、
@ annotate(<signature>)形式です。signatureパラメーターは、入力パラメーターのデータ型とUDAFの戻り値を定義するために使用されます。 関数シグネチャの詳細については、「関数シグネチャとデータ型」をご参照ください。カスタムPythonクラス (派生クラス): 必須です。
カスタムPythonクラスは、UDAFコードの組織単位です。 このクラスは、ビジネス要件を満たすために使用される変数とメソッドを定義します。 UDAFコードでは、MaxComputeにインストールされているサードパーティライブラリを参照したり、ファイルやテーブルを参照したりすることもできます。 詳細については、「サードパーティライブラリ」または「リファレンスリソース」をご参照ください。
Pythonクラスを実装するメソッド: required.
次の表に、Pythonクラスの実装に使用できる4つのメソッドを示します。 ビジネス要件に基づいて方法を設定できます。
移動方法
説明
BaseUDAF.new_buffer()UDAFの中間値バッファを返します。
bufferは、LISTやDICTなどのマーシャリング可能なオブジェクトである必要があります。bufferサイズはデータ量に応じて大きくすることはできません。 極端な場合、マーシャリング操作後のbufferサイズは2 MBを超えることはできません。BaseUDAF.iterate(buffer[, args, ...])argsを中間値bufferに集約します。BaseUDAF.merge(buffer, pbuffer)pbufferと中間値bufferのマージ結果をbufferに格納します。BaseUDAF.terminate (buffer)MaxCompute SQLで
bufferを基本データ型の値に変換します。
サンプルコード:
#coding:utf-8
# Import the function signature module and base classes.
from odps.udf import annotate
from odps.udf import BaseUDAF
# The function signature.
@annotate('double->double')
# The custom Python class.
class Average(BaseUDAF):
# Methods to implement Python classes.
def new_buffer(self):
return [0, 0]
def iterate(self, buffer, number):
if number is not None:
buffer[0] += number
buffer[1] += 1
def merge(self, buffer, pbuffer):
buffer[0] += pbuffer[0]
buffer[1] += pbuffer[1]
def terminate(self, buffer):
if buffer[1] == 0:
return 0.0
return buffer[0] / buffer[1]制限事項
MaxComputeでは、Python 2.7でPython 2 UDAFを記述し、サンドボックス環境でUDAFコードを実行できます。 この環境では、以下の操作は禁止されています。
ローカルファイルからデータを読み取り、データを書き込みます。
サブプロセスを開始します。
スレッドを開始します。
ソケット通信を有効にします。
他のシステムを使用してPython 2 UDFを呼び出します。
これらの制限により、アップロードするコードはPython標準ライブラリを使用して記述する必要があります。 Python標準ライブラリのモジュールまたはC拡張モジュールが上記の操作に関与している場合、これらのモジュールは使用できません。 Python標準ライブラリのモジュールに関する次の点に注意してください。
Python標準ライブラリに基づいて実装され、拡張モジュールに依存しないすべてのモジュールが利用可能です。
次のC拡張モジュールを使用できます。
arrayとaudioop
binasciiとbisect
cmath、_codecs_cn、_codecs_hk、_codecs_iso2022、_codecs_jp、_codecs_kr、_codecs_tw、_collections、およびcStringIO
datetime
_functoolsとfuture_builtins
_heapqおよび_hashlib
itertools
_json
_localeおよび_lsprof
math、_md5、および_multibytecodec
operator
_random
_sha256、_sha512、_sha、_struct、およびstrop
time
unicodedata
_weakref
cPickle
サンドボックス環境でUDFコードを実行する場合、標準出力 (sys.stdout) または標準エラー出力 (
sys.stderr) に書き込むことができるデータの最大サイズは20 KBです。 サイズが20 KBを超える場合、余分な文字は無視されます。
サードパーティライブラリ
NumPyなどのサードパーティライブラリは、標準ライブラリの補足としてMaxComputeのPython 2環境にインストールされます。
サードパーティのライブラリの使用には、いくつかの制限があります。 たとえば、サードパーティのライブラリを使用する場合、ローカルデータへのアクセスは許可されず、限られたネットワークI/Oリソースしか使用できません。 サードパーティライブラリの関連APIは無効になっています。
関数シグネチャとデータ型
関数シグネチャの形式:
@annotate(<signature>)signatureパラメーターは、入力パラメーターと戻り値のデータ型を指定する文字列です。 UDAFを実行する場合、入力パラメーターのデータ型とUDAFの戻り値は、関数シグネチャで指定されたデータ型と一致している必要があります。 データ型の整合性は、セマンティック解析中にチェックされます。 データ型に矛盾がある場合は、エラーが返されます。 関数シグネチャの形式:
'arg_type_list -> type'arg_type_list: 入力パラメーターのデータ型を指定します。 複数の入力パラメーターを使用する場合は、複数のデータ型を指定し、コンマ (,) で区切ります。 BIGINT、STRING、DOUBLE、BOOLEAN、DATETIME、DECIMAL、FLOAT、BINARY、DATE、DECIMAL(precision、scale) 、CHAR、VARCHAR、複合データ型 (ARRAY、MAP、STRUCT) 、およびネストされた複合データ型がサポートされています。arg_type_listは、アスタリスク (*) または空のまま ('') で表すことができます。arg_type_listがアスタリスク (*) で表される場合、ランダムな数の入力パラメーターが許可されます。arg_type_listが空 ('') の場合、入力パラメーターは使用されません。
@ Resolveアノテーションの構文拡張機能の詳細については、「UDAFおよびUDTFの動的パラメーター」をご参照ください。
typeは、戻り値のデータ型を指定します。 UDAFの場合、値の1列のみが返されます。 BIGINT、STRING、DOUBLE、BOOLEAN、DATETIME、DECIMAL、FLOAT、BINARY、DATE、DECIMAL(precision、scale) のデータ型がサポートされています。 ARRAY、MAP、STRUCTなどの複雑なデータ型、およびネストされた複雑なデータ型もサポートされています。
UDAFコードを記述するときに、MaxComputeプロジェクトで使用されるデータ型エディションに基づいてデータ型を選択できます。 データ型のエディションと各エディションでサポートされているデータ型の詳細については、「データ型のエディション」をご参照ください。
次の表に、有効な関数シグネチャの例を示します。
関数署名 | 説明 |
| 入力パラメーターのデータ型はBIGINTとDOUBLEで、戻り値のデータ型はSTRINGです。 |
| ランダムな数の入力パラメーターが使用され、戻り値のデータ型はSTRINGです。 |
| 入力パラメーターは使用されず、戻り値のデータ型はDOUBLEです。 |
| 入力パラメーターのデータ型はARRAY<BIGINT> 、戻り値のデータ型はSTRUCT<x:STRING, y:INT> です。 |
次の表に、MaxCompute SQLでサポートされているデータ型とPython 2データ型の間のマッピングを示します。 データ型の一貫性を確保するには、マッピングに基づいてPython UDAFを記述する必要があります。 次の表に、データ型のマッピングについて説明します。
MaxCompute SQLデータ型 | Python 2データ型 |
BIGINT | INT |
STRING | STR |
DOUBLE | FLOAT |
BOOLEAN | BOOL |
DATETIME | INT |
FLOAT | FLOAT |
CHAR | STR |
VARCHAR | STR |
BINARY | BYTEARRAY |
DATE | INT |
DECIMAL | DECIMAL.DECIMAL |
ARRAY | LIST |
MAP | DICT |
STRUCT | COLLECTIONS.NAMEDTUPLE |
MaxCompute SQLでサポートされているDATETIME型は、Pythonデータ型INTにマップされます。 INT型の値は、1970年1月1日木曜日00:00:00から経過したミリ秒数です。 Python標準ライブラリのDATETIMEモジュールを使用して、DATETIME型のデータを処理できます。
silentパラメーターがodps.udf.int(value)に追加されます。silentパラメーターがTrueに設定されていて、valueのデータ型をINT型に変換できない場合、Noneが返され、エラーは返されません。MaxCompute SQLのNULLは、Python 2ではNoneにマップされます。
参照リソース
odps.distcacheモジュールを使用して、Python 2 UDAFコードでファイルとテーブルを参照できます。
odps.distcache.get_cache_file(resource_name): 特定のファイルの内容を返します。resource_nameは、MaxComputeプロジェクト内の既存のファイルの名前を指定する文字列です。 ファイル名が無効であるか、ファイルが存在しない場合は、エラーが返されます。説明UDAFコードでファイルを参照するには、UDAFを作成するときにファイルを宣言する必要があります。 それ以外の場合、UDAFを呼び出すとエラーが返されます。
戻り値はファイルのようなオブジェクトです。 このオブジェクトが使用されなくなった場合は、
closeメソッドを呼び出してファイルを解放する必要があります。
odps.distcache.get_cache_table(resource_name): 特定のテーブルの内容を返します。resource_nameは、MaxComputeプロジェクト内の既存のテーブルの名前を指定する文字列です。 テーブル名が無効であるか、テーブルが存在しない場合は、エラーが返されます。戻り値はGENERATOR型です。 呼び出し元はテーブルをトラバースしてテーブルの内容を取得します。 ARRAYタイプのレコードは、呼び出し元がテーブルをトラバースするたびに取得されます。
詳細については、「リファレンスリソース (Python 2 UDF) 」および「リファレンスリソース (Python 2 UDTF) 」をご参照ください。
使用上の注意
概要 の手順に従ってPython 2 UDAFを開発した後、MaxCompute SQLを使用してこのUDAFを呼び出すことができます。 次の手順では、Python 2 UDAFを呼び出す方法について説明します。
MaxComputeプロジェクトでUDFを使用する: この方法は、組み込み関数を使用する方法と似ています。
プロジェクト間でUDFを使用する: プロジェクトaでプロジェクトBのUDFを使用します。次のステートメントは、例を示します。
select B:udf_in_other_project(arg0, arg1) as res from table_t;プロジェクト間共有の詳細については、「パッケージに基づくプロジェクト間リソースアクセス」をご参照ください。
MaxCompute Studioを使用してPython 2 UDAFを開発および呼び出す方法の詳細については、「Python UDFの開発」をご参照ください。