在Apache Spark 2.4中为复杂数据类型引入了新的内置函数和高阶函数
2018年11月16日 在工程的博客
Apache Spark 2.4介绍了29个新的内置函数,用于操作复杂类型(例如,数组类型),包括高阶函数。
在Spark 2.4之前,对于直接操作复杂类型,有两种典型的解决方案:1)将嵌套结构分解成单独的行,并应用一些函数,然后重新创建结构2)构建用户定义函数(UDF)。
相比之下,新的内置函数可以直接操作复杂类型,而高阶函数可以使用与udf类似的匿名lambda函数操作复杂值,但性能要好得多。
在本博客中,通过一些示例,我们将展示其中一些新的内置函数,以及如何使用它们来操作复杂的数据类型。
典型解决方案
让我们先用下面的示例回顾一下典型的解决方案。
选项1 -爆炸和收集
我们使用爆炸将数组分解成单独的行并求值Val + 1
,然后使用collect_list重新构造数组,如下所示:
选择id,collect_list (val+1)作为瓦尔斯从(选择id,爆炸(val)作为瓦尔从input_tbl) x集团通过id
这很容易出错,而且效率很低,原因有三。首先,我们必须努力确保重新收集的数组完全是由原始数组组成的,方法是根据唯一键对它们进行分组。其次,我们需要一个group by
,表示shuffle操作;shuffle操作不保证保持从原始数组中重新收集的数组的元素顺序。最后,它很昂贵。
选项2 -用户定义函数
接下来,我们使用Scala UDF,它接受Seq[Int],并在其中的每个元素中添加1:
def addOne (值: Seq [Int): Seq [Int]={values.map (价值=>价值+1)}val plusOneInt=spark.udf。寄存器("plusOneInt", addOne(_: Seq[Int): Seq [Int])
或者我们也可以使用Python UDF,然后:
SELECT id, plusOneInt(vals)作为瓦尔斯从input_tbl
这种方法更简单、更快,而且没有正确性缺陷,但是由于将数据序列化到Scala或Python的代价可能很高,因此效率可能仍然很低。
你可以在一本笔记本上看到这些例子我们发布的博客试试吧。
新增内置函数
让我们看看直接操作复杂类型的新内置函数。的笔记本列出每个函数的示例。每个函数的签名和参数都用它们各自的类型T或U进行注释,以表示数组元素类型,K, V表示映射和值类型。
高阶函数
为了进一步操作数组和映射类型,我们使用SQL中已知的匿名lambda函数和高阶函数语法,将lambda函数作为参数。
lambda函数的语法如下:
参数- >函数身体(论点1,论点2,…) - - - >函数身体
左边的符号->定义了参数列表,右边定义了函数体,函数体可以使用其中的参数和其他变量来计算新值。
使用匿名Lambda函数进行转换
我们来看一个例子变换
使用匿名lambda函数的函数。
这里我们有一个包含3列的数据表:一个键作为整数;整数数组的值;和nested_values of array of integer。
关键 | 值 | nested_values |
---|---|---|
1 | [1,2,3] | [[1,2,3], [], [4,5]] |
当我们执行以下SQL语句时:
选择变换(值、元素->元素+1)从数据;
的变换
函数遍历数组并应用lambda函数,将每个元素加1,并创建一个新数组。
除了参数之外,我们还可以使用其他变量,例如:key,它来自lambda函数中的外部上下文,即表的一列:
选择变换(值、元素->元素+键)从数据;
如果你想操作一个深度嵌套的列,比如本例中的nested_values,你可以使用嵌套lambda函数:
选择变换(nested_values,加勒比海盗->变换(加勒比海盗,元素->元素+关键+大小(arr)))从数据;
你可以使用关键
而且加勒比海盗
在内部lambda函数中,来自外部上下文的表的列和外部lambda函数的参数。
注意,您可以在它们的笔记本中看到与典型解决方案相同的示例,而其他高阶函数的示例则包含在内置函数的笔记本中。
结论
Spark 2.4引入了24个新的内置功能,例如array_union
,array_max /分钟
等,以及5个高阶函数,如变换
,过滤器
等,用于操作复杂类型。整个列表和他们的例子都在这里笔记本。如果您有任何复杂的值,请考虑使用它们,并让我们知道任何问题。
我们要感谢Apache Spark社区的贡献者Alex Vayda、Bruce Robbins、Dylan Guedes、Florent Pepin、H Lu、Huaxin Gao、Kazuaki Ishizaki、Marco Gaido、Marek Novotny、Neha Patil、Sandeep Singh以及其他许多人。
阅读更多
要了解更多关于高阶函数和内置函数的信息,请参阅以下参考资料:
- 试附带的笔记本
- 阅读之前的文章关于高阶函数的博客
- 看Spark + AI欧洲峰会讨论高阶函数