在 MaxCompute UDF 中運行 Scipy

摘要: 新版 MaxCompute Isolation Session 支持 Python UDF。也就是說,Python UDF 中已經能夠跑二進制包。剛纔以 Scipy 爲例踩了一下坑,把相關的過程分享出來。html

新版 MaxCompute Isolation Session 支持 Python UDF。也就是說,Python UDF 中已經能夠跑二進制包。剛纔以 Scipy 爲例踩了一下坑,把相關的過程分享出來。python

下載 Scipy 包並上傳資源

首先,從 PyPI 或其餘鏡像下載 Scipy 包。你須要下載後綴爲「cp27-cp27m-manylinux1_x86_64.whl」的包,其餘的包會沒法加載,包括名爲「cp27-cp27mu」的包。如下的截圖來自 https://pypi.python.org/pypi/scipy ,僅有打勾的包能夠直接使用:linux

下載 whl 後,將文件名更改成 scipy.zip。此後,在 MaxCompute Console 中執行session

add archive scipy.zip;

此後,scipy.zip 即被建立爲 MaxCompute Archive 資源。不建議使用其餘類型的資源,由於在執行時,MaxCompute 會自動解壓 Archive 類型的資源,從而省去手動解壓的步驟。app

從非 Whl 包生成 Whl 包

若是列出的包中包含 Whl,則能夠直接上傳並跳過此步驟。若是列出的包不包含 whl(如手中僅有圖中的 scipy-0.19.0.zip),須要在 Linux 環境中手動編譯並打包爲 whl。打包前,須要確保下列命令返回「cp27m」而不是「cp27mu」:函數

python -c "import pip; print pip.pep425tags.get_abi_tag()"

若是返回值爲「cp27mu」,你須要使用 「--enable-unicode=no" 選項編譯一個可用的 Python 2.7,再使用編譯獲得的 Python。若是返回值正確,一般能夠在該環境下使用lua

python setup.py bdist_wheel

完成,具體請參考各個包的編譯/安裝說明。spa

打包完成後,將生成的 whl 包上傳。code

編寫和建立 UDF

咱們須要編寫一個 UDF 支持計算 psi。編寫下列代碼:orm

from odps.udf import annotate
from odps.distcache import get_cache_archive

def include_package_path(res_name):
    import os, sys
    archive_files = get_cache_archive(res_name)
    dir_names = sorted([os.path.dirname(os.path.normpath(f.name)) for f in archive_files
                       if '.dist_info' not in f.name], key=lambda v: len(v))
    sys.path.append(os.path.dirname(dir_names[0]))

@annotate("double->double")
class MyPsi(object):
    def __init__(self):        
        include_package_path('scipy.zip')

    def evaluate(self, arg0):
        from scipy.special import psi
        return float(psi(arg0))

這裏有必要解釋一下 include_package_path 這個函數。get_cache_archive 返回一個包含包中全部文件的文件對象。咱們首先取出全部的文件名,此後得到最短的路徑做爲包的路徑,並加入 sys.path。此後,即可以正常 import scipy 這個包。

須要注意的是,由於 MaxCompute 會在執行前經過原有的沙箱檢查 UDF 的輸入/輸出,於是 include_package_path 和 import 在函數外調用會報錯。

編寫完成後,將代碼保存爲 my_psi.py,並在 MaxCompute Console 中執行

add py my_psi.py;

此後建立函數。在 MaxCompute Console 中輸入

create function my_psi as my_psi.MyPsi using my_psi.py,scipy.zip;

注意在 create function 時,不要忘記加上剛纔上傳的包,例如上面的 scipy.zip。

執行

建立 UDF 後,即可以在 MaxCompute Console 中執行查詢(暫不支持 pypy,於是需禁用 pypy):

set odps.pypy.enabled=false;
set odps.isolation.session.enable = true;
select my_psi(sepal_length) from iris;

其餘

若是包依賴了其餘 Python 包,須要一併上傳並同時加入到 UDF 依賴中。

使用 0.7.4 以上的 PyODPS DataFrame 能夠簡化使用二進制包的 UDF 的編寫,無需手動調用 include_package_path,具體可見 http://pyodps.readthedocs.io/zh_CN/latest/df-element-zh.html#third-party-library 。

原文連接

相關文章
相關標籤/搜索