跳到主要内容
工程的博客

在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 [Intvalues.map (价值>价值+1val plusOneIntspark.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_unionarray_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以及其他许多人。

阅读更多

要了解更多关于高阶函数和内置函数的信息,请参阅以下参考资料:

  1. 附带的笔记本
  2. 阅读之前的文章关于高阶函数的博客
  3. Spark + AI欧洲峰会讨论高阶函数
免费试用Databricks
看到所有工程的博客的帖子