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,我们⾸先模拟⼀张数据表,为了简单起见,该表仅有⼀⾏⼀列数据:
我们模拟了⼀张数据表temp_table,该表仅有⼀列,其中列名称为col,列类型为字符串且不允许包含N
hive 字符串转数组ull,输出结果:
我们在表temp_table的基础之上演⽰UDF的使⽤⽅法:
⾸先我们定义⼀个普通的Python函数:func_string,为了简单起见它没有任何参数,仅仅返回⼀个简单的字符串;
然后我们通过HiveContext registerFunction即可以将函数func_string注册为UDF,registerFunction接收两个参数:UDF名称、UDF关联的Python函数;
最后我们可以在Spark(Hive) SQL中使⽤这个UDF,输出结果:
我们需要注意的是,HiveContext registerFunction实际上有三个参数:
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
(2)ArrayType
注意:ArrayType(数组)必须确保元素类型的⼀致性,如指定UDF返回值类型为ArrayType(IntegerType()),则函数func_array的返回值类型必须为list或tuple,其中的元素类型必须为int。
(3)StructType
注意:StructType必须确保函数的返回值类型为tuple,⽽且使⽤HiveContext registerFunction注册UDF时需要依次为其中的元素指定名称各类型,如上述⽰例中每⼀个元素的名称为first,类型为IntegerType;第⼆个元素的名称为second,类型为FloatType;第三个元素的名称为third,类型为StringType。
(4)MapType
注意:MapType必须确保函数的返回值类型为dict,⽽且所有的“key”应保持类型⼀致,“value”也就保持
类型⼀致。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论