在DataFrame上定义自定义方法的最佳方法是什么?

Pra*_*akh 10 scala apache-spark apache-spark-sql

我需要在DataFrame上定义自定义方法.有什么更好的方法呢?解决方案应该是可扩展的,因为我打算定义大量的自定义方法.

我当前的方法是MyClass使用DataFrameas参数创建一个类(比如说),在其中定义我的自定义方法(比如说customMethod)并定义一个转换DataFrame为的隐式方法MyClass.

implicit def dataFrametoMyClass(df: DataFrame): MyClass = new MyClass(df)
Run Code Online (Sandbox Code Playgroud)

因此,我可以打电话:

dataFrame.customMethod()
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?公开征求意见.

Mar*_*nne 14

你的方式是要走的路(见[1]).虽然我解决了一点不同,但方法仍然类似:

可能性1

Implicits

object ExtraDataFrameOperations {
  object implicits {
    implicit def dFWithExtraOperations(df: DataFrame) = DFWithExtraOperations(df)
  }
}

case class DFWithExtraOperations(df: DataFrame) {
  def customMethod(param: String) : DataFrame = {
    // do something fancy with the df
    // or delegate to some implementation
    //
    // here, just as an illustrating example: do a select
    df.select( df(param) )
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

要在以下方面使用新customMethod方法DataFrame:

import ExtraDataFrameOperations.implicits._
val df = ...
val otherDF = df.customMethod("hello")
Run Code Online (Sandbox Code Playgroud)

可能性2

implicit method您也可以使用implicit class:而不是使用(见上文):

隐含的类

object ExtraDataFrameOperations {
  implicit class DFWithExtraOperations(df : DataFrame) {
     def customMethod(param: String) : DataFrame = {
      // do something fancy with the df
      // or delegate to some implementation
      //
      // here, just as an illustrating example: do a select
      df.select( df(param) )
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

import ExtraDataFrameOperations._
val df = ...
val otherDF = df.customMethod("hello")
Run Code Online (Sandbox Code Playgroud)

备注

如果您想要阻止其他内容import,请将其object ExtraDataFrameOperations转换为package object并将其存储在package.scala包中调用的文件中.

官方文件/参考资料

[1] M. Odersky的原创博客"Pimp my library"可在http://www.artima.com/weblogs/viewpost.jsp?thread=179766上找到.


Ale*_*nov 8

有一种稍微简单的方法:只需声明MyClassimplicit

implicit class MyClass(df: DataFrame) { def myMethod = ... }
Run Code Online (Sandbox Code Playgroud)

这会自动创建隐式转换方法(也称为MyClass).您还可以通过添加来使其成为值类,extends AnyVal这可以通过MyClass在运行时实际创建实例来避免一些开销,但这在实践中很不重要.

最后,将MyClass进入一个package object可以让你在任何地方使用新的方法,在这个包,而无需进口MyClass,这可能是一个利益或者你的缺点.