提问者:小点点

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


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

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

implicit def dataFrametoMyClass(df: DataFrame): MyClass = new MyClass(df)

因此,我可以调用:

dataFrame.customMethod()

这是正确的做法吗?公开征求建议。


共3个答案

匿名用户

你的路就是你要走的路(参见[1])。尽管我解决了一个有点不同的问题,但方法仍然是相似的:

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) )
  }
}

要在DataFrame上使用新的customMethod方法:

import ExtraDataFrameOperations.implicits._
val df = ...
val otherDF = df.customMethod("hello")

您也可以使用隐式类,而不是使用隐式方法(见上文):

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) )
    }
  }
}
import ExtraDataFrameOperations._
val df = ...
val otherDF = df.customMethod("hello")

如果您想阻止额外的导入,请将对象ExtraDataFrame操作转换为包对象,并将其存储在包内名为package.scala的文件中。

[1]M. Odersky的原始博客“皮条客我的图书馆”可在http://www.artima.com/weblogs/viewpost.jsp?thread=179766

匿名用户

有一个稍微简单的方法:只需将MyClass声明为隐式

implicit class MyClass(df: DataFrame) { def myMethod = ... }

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

最后,将MyClass放入包对象将允许您在该包中的任何位置使用新方法,而不需要导入MyClass,这对您来说可能是一个好处或缺点。

匿名用户

我认为您应该在DataFrame和您的自定义包装器之间添加一个隐式转换,但是使用一个隐式的class——这应该是最容易使用的,并且您将在一个公共的地方存储您的自定义方法。

   implicit class WrappedDataFrame(val df: DataFrame) {
        def customMethod(String arg1, int arg2) {
           ...[do your stuff here]
        }
     ...[other methods you consider useful, getters, setters, whatever]...
      }

如果隐式包装器在DataFrame的范围内,您可以使用普通的DataFrame,就好像它是您的包装器一样,即:

df.customMethod(“test”, 100)