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

时间:2015-09-15 12:06:41

标签: scala apache-spark apache-spark-sql

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

我目前的方法是创建一个以MyClass为参数的类(比如DataFrame),在其中定义我的自定义方法(比如说customMethod)并定义一个隐式方法来转换{ {1}}至DataFrame

MyClass

因此我可以致电:

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

这是正确的方法吗?打开建议。

3 个答案:

答案 0 :(得分:14)

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

可能性1

Implicits

PM> Get-Package | Select-Object Id,LicenseUrl

Id                                                                                                  LicenseUrl                                                                                         
--                                                                                                  ----------                                                                                                                                                                                                                                                        
Castle.Core                                                                                                                                                                                            
CommonServiceLocator                                                                                                                                                                                   
Microsoft.AspNet.Mvc                                                                                                                                                                                   
Microsoft.AspNet.Razor                                                                                                                                                                                 
Microsoft.AspNet.WebApi                                                                                                                                                                                
Microsoft.AspNet.WebApi.Client                                                                                                                                                                         
Microsoft.AspNet.WebApi.Core                                                                                                                                                                           
Microsoft.AspNet.WebApi.WebHost                                                                                                                                                                        
Microsoft.AspNet.WebPages                                                                                                                                                                              
Microsoft.Web.DistributedCache                                                                                                                                                                         
Microsoft.Web.Infrastructure        

用法

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) ) } } 上使用新的customMethod方法:

DataFrame

可能性2

您可以使用import ExtraDataFrameOperations.implicits._ val df = ... val otherDF = df.customMethod("hello")

而不是使用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) )
    }
  }
}

备注

如果您想阻止其他import ExtraDataFrameOperations._ val df = ... val otherDF = df.customMethod("hello") ,请将import object转换为ExtraDataFrameOperations并将其存储在名为package object的文件中你的包裹。

官方文件/参考资料

[1]最初的博客"皮条客我的图书馆" M. Odersky先生可以http://www.artima.com/weblogs/viewpost.jsp?thread=179766

获取

答案 1 :(得分:8)

有一种稍微简单的方法:只需declare MyClass as implicit

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

这会自动创建隐式转换方法(也称为MyClass)。您还可以通过添加extends AnyVal使其成为value class,这可以避免因运行时实际创建MyClass实例而产生的一些开销,但实际上这很不重要。

最后,将MyClass放入package object将允许您在此包中的任何位置使用新方法,而无需导入MyClass,这可能是您的好处或缺点

答案 2 :(得分:0)

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

   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)