ODPS_ele—UDF Python API
自定义函数(UDF)
UDF全称User Defined Function,即用户自定义函数。ODPS提供了很多内建函数来满足用户的计算需求,同时用户还可以通过创建自定义函数来满足不同的计算需求。UDF在使用上与普通的 SQL内建函数 类似。
在ODPS中,用户可以扩展的UDF有三种,分别是:
UDF 分类 | 描述
User Defined Scalar Function 通常也称之为UDF
自定义函数,准确的说是用户自定义标量函数 (User Defined Scalar Function)。UDF的输入与输 出是一对一的关系,即读入一行数据, 写出一条输出值。UDAF(User Defined Aggregation Function)
自定义聚合函数,其输入与输出是多对一的关系, 即将多条输入记录聚合成一条输出值。可以与 SQL中的Group By语句联用。具体语法请参考聚合函数 。UDTF(User Defined Table Valued Function)
自定义表函数,是用来解决一次函数调用输出 多行数据场景的,也是唯一能返回多个字段的自定 义函数。而UDF及UDAF只能一次计算输出一条 返回值。
注解
UDF广义的说法代表了自定义标量函数,自定义聚合函数及自定义表函数三种类型的自定义函数的集合。狭义来说,仅代表用户自定义标量函数。文档会经常使用这一名词,请读者根据文档上下文判断具体含义。
受限环境
ODPS UDF的Python版本为2.7,并以沙箱模式执行用户代码,即代码是在一个受限的运行环境中执行的,在这个环境中,被禁止的行为包括:
- 读写本地文件
- 启动子进程
- 启动线程
- 使用socket通信
- 其他系统调用
基于上述原因,用户上传的代码必须都是纯Python实现,C扩展模块是被禁止的。
此外,Python的标准库中也不是所有模块都可用,涉及到上述功能的模块都会被禁止。具体标准库可用模块说明如下:
- 所有纯Python实现(不依赖扩展模块)的模块都可用
- C实现的扩展模块中下列模块可用
|
- 部分模块功能受限。比如沙箱限制了用户代码最多能往标准输出和标准错误输出写出数据的大小,即``sys.stdout/sys.stderr``最多能写20Kb,多余的字符会被忽略。
第三方库
运行环境中还安装了除标准库以外比较常用的三方库,做为标准库的补充。支持的三方库列表如下:
- numpy
警告
三方库的使用同样受到禁止本地、网络IO或其他在受限环境下的限制,因此三方库中涉及到相关功能的API也是被禁止的。
参数与返回值类型
@odps.udf.annotate(signature)
Python UDF目前支持ODPS SQL数据类型有:bigint, string, double, boolean和datetime。SQL语句在执行之前,所有函数的参数类型和返回值类型必须确定。因此对于Python这一动态类型语言,需要通过对UDF类加decorator的方式指定函数签名。
函数签名signature通过字符串指定,语法如下:
|
- 箭头左边表示参数类型,右边表示返回值类型。
- 只有UDTF的返回值可以是多列, UDF和UDAF只能返回一列。
- ‘*’代表变长参数,使用变长参数,UDF/UDTF/UDAF可以匹配任意输入参数。
下面是合法的signature的例子:
# UDTF参数为bigint、boolean,返回值为string,datetime
输入参数任意
|
Query语义解析阶段会将检查到不符合函数签名的用法,抛出错误禁止执行。执行期,UDF函数的参数会以函数签名指定的类型传给用户。用户的返回值类型也要与函数签名指定的类型一致,否则检查到类型不匹配时也会报错。ODPS SQL数据类型对应Python类型如下:
注解
|
odps.udf.int(value[, silent=True])
Python builtin函数 int 的修改。增加了参数 silent 。当 silent 为 True 时,如果 value 无法转为 int ,不会抛出异常,而是返回 None 。
UDF
实现Python UDF非常简单,只需要定义一个new-style class,并实现 evaluate 方法。下面是一个例子:
|
注解:Python UDF必须通过annotate指定函数签名
UDAF
- class odps.udf.BaseUDAF
-
继承此类实现Python UDAF。
- BaseUDAF.new_buffer()
-
实现此方法返回聚合函数的中间值的buffer。buffer必须是mutable object(比如list, dict),并且buffer的大小不应该随数据量递增,在极限情况下,buffer marshal过后的大小不应该超过2Mb。
- BaseUDAF.iterate(buffer[, args, ...])
-
实现此方法将args聚合到中间值buffer中。
- BaseUDAF.merge(buffer, pbuffer)
-
实现此方法将两个中间值buffer聚合到一起,即将pbuffer merge到buffer中。
- BaseUDAF.terminate(buffer)
-
实现此方法将中间值buffer转换为ODPS SQL基本类型。
下面是一个UDAF求平均值的例子。
|
UDTF
- class odps.udf.BaseUDTF
-
Python UDTF的基类,用户继承此类,并实现 process, close 等方法。
- BaseUDTF.__init__()
-
初始化方法,继承类如果实现这个方法,则必须在一开始调用基类的初始化方法 super(BaseUDTF,self).__init__() 。
__init__ 方法在整个UDTF生命周期中只会被调用一次,即在处理第一条记录之前。当UDTF需要保存内部状态时,可以在这个方法中初始化所有状态。
- BaseUDTF.process([args, ...])
-
这个方法由ODPS SQL框架调用,SQL中每一条记录都会对应调用一次 process , process 的参数为SQL语句中指定的UDTF输入参数。
- BaseUDTF.forward([args, ...])
-
UDTF的输出方法,此方法由用户代码调用。每调用一次 forward ,就会输出一条记录。 forward 的参数为SQL语句中指定的UDTF的输出参数。
- BaseUDTF.close()
-
UDTF的结束方法,此方法由ODPS SQL框架调用,并且只会被调用一次,即在处理完最后一条记录之后。
下面是一个UDTF的例子。
|
注解
Python UDTF也可以不加annotate指定参数类型和返回值类型。这样,函数在SQL中使用时可以匹配任意输入参数,但返回值类型无法推导,所有输出参数都将认为是string类型。因此在调用 forward 时,就必须将所有输出值转成 str 类型。
引用资源
Python UDF可以通过 odps.distcache 模块引用资源文件,目前支持引用文件资源和表资源。
- odps.distcache.get_cache_file(resource_name)
-
release-2012.09.03 新版功能.
返回指定名字的资源内容。 resource_name 为 str 类型,对应当前Project中已存在的资源名。如果资源名非法或者没有相应的资源,会抛出异常。
返回值为 file-like object ,在使用完这个object后,调用者有义务调用 close 方法释放打开的资源文件。
下面是使用 get_cache_file 的例子:
|
odps.distcache.get_cache_table(resource_name)
release-2012.11.14 新版功能.
返回指定资源表的内容。 resource_name 为 str 类型,对应当前Project中已存在的资源表名。如果资源名非法或者没有相应的资源,会抛出异常。
返回值为 generator 类型,调用者通过遍历获取表的内容,每次遍历得到的是以 tuple 形式存在的表中的一条记录。
下面是使用 get_cache_table 的例子:
|
注意事项
表达式优化
当一个Query中有多个相同UDF,并且他们的参数也都一致时,这些UDF在执行时会被优化成只执行一次。例如:
- random.seed(12345)
- @annotate('bigint->bigint')
- class MyRand(object):
- def evaluate(self, a):
- return random.randint(0, 10)
实现一个Rand函数,希望每次调用Rand时返回一个随机值。
- > select MyRand(c_int_a), MyRand(c_int_a) from udf_test;
- +------------+------------+
- | _c0 | _c1 |
- +------------+------------+
- | 4 | 4 |
- | 0 | 0 |
- | 9 | 9 |
- | 3 | 3 |
- +------------+------------+
可以看到默认情况下,同一行的两次Rand调用返回值结果一样,这是因为被优化后只执行一次导致的。如果不想要这个优化,可以通过设置配置项odps.sql.udf.optimize.reuse 取消这个优化:
- > set odps.sql.udf.optimize.reuse=false;
- > select MyRand(c_int_a), MyRand(c_int_a) from udf_test;
- +------------+------------+
- | _c0 | _c1 |
- +------------+------------+
- | 4 | 0 |
- | 9 | 3 |
- | 4 | 2 |
- | 6 | 1 |
- +------------+------------+
总结
ODPS为Python提供的类有
1. 参数与返回值类型
@odps.udf.annotate(signature),ODPS SQL数据类型对应Python类型如下:
odps.udf.int(value[, silent=True])
2. UDF
# 定义一个new-style class,并实现 evaluate 方法
|
3. UDAF
class odps.udf.BaseUDAF—继承此类实现Python UDAF。
BaseUDAF类拥有的四个方法如下:
- BaseUDAF.new_buffer()
- BaseUDAF.iterate(buffer[, args, ...])
- BaseUDAF.merge(buffer, pbuffer)
- BaseUDAF.terminate(buffer)¶
-
下面是一个UDAF求平均值的例子。
|
4.UDTF
class odps.udf.BaseUDTF—Python UDTF的基类,用户继承此类,并实现 process , close 等方法。
BaseUDTF类拥有的四个方法
- BaseUDTF.__init__()
- BaseUDTF.process([args, ...])
- BaseUDTF.forward([args, ...])
- BaseUDTF.close()
- 下面是一个UDTF的例子。
|
ODPS_ele—UDF Python API的更多相关文章
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (一)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (四)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- 如何在 Apache Flink 中使用 Python API?
本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...
- Appium python API 总结
Appium python api 根据testerhome的文章,再补充一些文章里面没有提及的API [TOC] [1]find element driver 的方法 注意:这几个方法只能通过sel ...
- The novaclient Python API
The novaclient Python API Usage First create a client instance with your credentials: >>> f ...
- Openstack python api 学习文档 api创建虚拟机
Openstack python api 学习文档 转载请注明http://www.cnblogs.com/juandx/p/4953191.html 因为需要学习使用api接口调用openstack ...
- BotVS开发基础—Python API
代码 import json def main(): # python API列表 https://www.botvs.com/bbs-topic/443 #状态信息 LogStatus(" ...
- 《Spark Python API 官方文档中文版》 之 pyspark.sql (二)
摘要:在Spark开发中,由于需要用Python实现,发现API与Scala的略有不同,而Python API的中文资料相对很少.每次去查英文版API的说明相对比较慢,还是中文版比较容易get到所需, ...
- HBase Python API
HBase Python API HBase通过thrift机制可以实现多语言编程,信息通过端口传递,因此Python是个不错的选择 吐槽 博主在Mac上配置HBase,奈何Zoomkeeper一直报 ...
随机推荐
- http-cache浏览器缓存
摘至知乎 首先得明确 http 缓存的好处 减少了冗余的数据传输,减少网费 减少服务器端的压力 Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间 加快客户端加载网页的速度 常见 ht ...
- 为什么说LAXCUS颠覆了我的大数据使用体验
切入正题前,先做个自我介绍. 本人是从业三年的大数据小码农一枚,在帝都一家有点名气的广告公司工作,同时兼着大数据管理员的职责. 平时主要的工作是配合业务部门,做各种广告大数据计算分析工作,然后制成各种 ...
- Vue.js 相关知识(动画)
1. 简介 Vue 在插入.更新或移除 DOM 时,提供多种不同方式的过渡效果,并提供 transition 组件来实现动画效果(用 transition 组件将需执行过渡效果的元素包裹) 语法:&l ...
- Daily Scrum NO.2
工作概况 符美潇(PM) 昨日完成的工作 1.Daily Scrum.日常会议及日常工作的分配和查收. 2.为两名团队新成员制定了任务并录入TFS. 今日工作 1.Daily Scrum.日常会议及日 ...
- Leetcode题库——46.全排列
@author: ZZQ @software: PyCharm @file: permute.py @time: 2018/11/15 19:42 要求:给定一个没有重复数字的序列,返回其所有可能的全 ...
- Linux换源
Linux换源 前言 最近学校的ipv6坏了,导致从deepin本身获取的源速度极慢,笔者实在忍无可忍,随后在同学指导下换了清华大学ipv4的源 步骤 sudo gedit /etc/apt/sour ...
- vs2013的安装及测试(第三周)
1.打开同学给的安装包,发现如下问题: 2.因为是win7,提示需安装IE10.因为安装IE10必须要在安装好 server pack 1的情况下,所以从官方网站上下载好server pack 1,并 ...
- 对于beta发布的评论
第一组:新蜂小组 题目:俄罗斯方块 评论:主体功能已经完成,可以流畅的进行游戏,看项目的完成度是最高的.他们不但把核心功能做出来了,界面也已基本完成. 第二组:Nice团队 题目:约跑APP(约吧) ...
- 一本通1646GT 考试
1646:GT 考试 时间限制: 1000 ms 内存限制: 524288 KB [题目描述] 阿申准备报名参加 GT 考试,准考证号为 n 位数 X1X2⋯Xn(0≤Xi≤9),他不 ...
- AtCoder Grand Contest 030 自闭记
A:阅读. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...