在 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 。

原文连接

相关文章
相关标签/搜索