Chaining Custom DataFrame Transformations in Spark
文章目录
在Spark中,可以采用implicit classes
或者Dataset#transform
来连接DataFrame的变换,这篇博客着重描如何连接DataFrame变换操作,并且详细解释说明为啥Dataset#transform
方式要比implicit classes
更有优势。
Dataset Transform方法
Dataset transform方法提供了concise syntax for chaining custom transformations
假如我们有两个方法
withGreeting()
方法,该方法在原有的DataFrame基础上增加greeting
列withFarewell()
方法,该方法在原有的DataFrame基础上增加farewell
列
1 | def withGreeting(df: DataFrame): DataFrame = { |
我们可以利用transform
方法来运行withGreeting()
和withFarewell()
1 | val df = Seq( |
当然,transform
方法也可以很容易和Spark DataFrame内置的方法结合在一起使用,例如select
1 | df |
如果我们不使用transform
,那么未来实现相同的功能,代码需要层层嵌套,大大降低了代码的可读性
1 | withFarewell(withGreeting(df)) |
Transform Method with Arguments
带参数的自定义DataFrame变化方法也能够通过transform
连接起来,但是必须要采用scala中的currying方式来实现
我们依然以上面的DataFrame为例,增加一个带有一个string参数的变化方法
1 | def withGreeting(df:DataFrame): DataFrame = { |
这时,我们可以使用transform
方法将withGreeting
和withCat
连接起来
1 | val df = Seq( |
Monkey Patching with Implicit Classes
Implicit classes能够将方法加入到已经存在的勒种,下面的例子就是将withGreeting
和withFarewell
加入到DataFrame这个类本身中
1 | object BadImplicit{ |
此时withGreeting()
和withFarewell
可以采用下面的方式串联起来执行
1 | import BadImplicit._ |
Avoid Implicit Classes
Changing base classes is known as monkey patching and is a delightful feature of Ruby but can be perilous in untutored hands. — Sandi Metz
虽然Sandi的评论针对的是Ruby语音,但是这个准则同样适用于scala
因此,在实际项目中,不建议采用Implici Classes, 况且,Spark已经提供了非常好用的transform
方法解决多个变化连接执行的问题。