python应用中调用spark_Spark(Hive) SQL中UDF的使用(Python)

相对于使用MapReduce或者Spark Application的方式进行数据分析,使用Hive SQL或Spark SQL能为我们省去不少的代码工作量,而Hive SQL或Spark SQL本身内置的各类UDF也为我们的数据处理提供了不少便利的工具,当这些内置的UDF不能满足于我们的需要时,Hive SQL或Spark SQL还为我们提供了自定义UDF的相关接口,方便我们根据自己的需求进行扩展。

在Hive的世界里使用自定义UDF的过程是比较复杂的。我们需要根据需求使用Java语言开发相应的UDF(UDAF、UDTF),然后将UDF的代码及其依赖编译打包为Jar,使用方法有两种:

(1)临时函数

在一次会话(Session)中使用如下语句创建临时函数:

ADD JAR /run/jar/udf_test.jar;

CREATE TEMPORARY FUNCTION my_add AS 'com.hive.udf.Add';

这种方式有一个缺点:每一次会话过程中使用函数时都需要创建,而且仅在当前会话中有效。

(2)永久函数

这个特性需要高版本的Hive支持,它的好处是可以将UDF Jar存放至HDFS,函数仅需要创建一次即可以永久使用,如下:

CREATE FUNCTION func.ipToLocationBySina AS 'com.sina.dip.hive.function.IPToLocationBySina' USING JAR 'hdfs://dip.cdh5.dev:8020/user/hdfs/func/location.jar';

虽然永久函数相对于临时函数有一定优势,但Java语言的开发门槛很大程度上妨碍了UDF在实际数据分析过程中使用,毕竟我们的数据分析师多数是以Python、SQL为主要分析工具的,每一次UDF的开发都需要工程师的参与,开发效率与应用效果都是不是很好(可能需要频繁更新UDF的问题),PySpark的出现确很好地解决了这个问题:它可以非常方便地将一个普通的Python函数注册为一个UDF。

为了说明如何在Spark(Hive) SQL中的使用Python UDF,我们首先模拟一张数据表,为了简单起见,该表仅有一行一列数据:

121862-20151102191626008-294505563.png

我们模拟了一张数据表temp_table,该表仅有一列,其中列名称为col,列类型为字符串且不允许包含Null,输出结果:

121862-20151102191641024-1281607897.png

我们在表temp_table的基础之上演示UDF的使用方法:

121862-20151102191650336-1720576580.png

首先我们定义一个普通的Python函数:func_string,为了简单起见它没有任何参数,仅仅返回一个简单的字符串;

然后我们通过HiveContext registerFunction即可以将函数func_string注册为UDF,registerFunction接收两个参数:UDF名称、UDF关联的Python函数;

最后我们可以在Spark(Hive) SQL中使用这个UDF,输出结果:

121862-20151102191700305-1355999183.png

我们需要注意的是,HiveContext registerFunction实际上有三个参数:

121862-20151102191710414-1276716036.png

name:UDF名称;

f:UDF关联的Python函数;

returnType:UDF(Python函数)返回值类型,默认为StringType()。

上述示例中因为我们的UDF函数的返回值类型为字符串,因此使用Hive registerFunction注册UDF时省略了参数returnType,即returnType默认值为StringType(),如果UDF(Python函数)的返回值类型不为字符串,则需要显式为其指定returnType。

我们以类型IntegerType、ArrayType、StructType、MapType为例演示需要显式指定returnType的情况。

(1)IntegerType

121862-20151102191721867-1423619324.png

121862-20151102191731555-1137056116.png

(2)ArrayType

121862-20151102191743414-228173969.png

121862-20151102191752617-1928473469.png

注意:ArrayType(数组)必须确保元素类型的一致性,如指定UDF返回值类型为ArrayType(IntegerType()),则函数func_array的返回值类型必须为list或tuple,其中的元素类型必须为int。

(3)StructType

121862-20151102191801992-117365176.png

121862-20151102191814117-236054503.png

注意:StructType必须确保函数的返回值类型为tuple,而且使用HiveContext registerFunction注册UDF时需要依次为其中的元素指定名称各类型,如上述示例中每一个元素的名称为first,类型为IntegerType;第二个元素的名称为second,类型为FloatType;第三个元素的名称为third,类型为StringType。

(4)MapType

121862-20151102191834446-1687702500.png

121862-20151102191945008-281308001.png

注意:MapType必须确保函数的返回值类型为dict,而且所有的“key”应保持类型一致,“value”也就保持类型一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值