我需要在DataFrame上定义自定义方法。有什么更好的方法呢?解决方案应该是可扩展的,因为我打算定义大量的自定义方法。
我目前的方法是创建一个以MyClass
为参数的类(比如DataFrame
),在其中定义我的自定义方法(比如说customMethod
)并定义一个隐式方法来转换{ {1}}至DataFrame
。
MyClass
因此我可以致电:
implicit def dataFrametoMyClass(df: DataFrame): MyClass = new MyClass(df)
这是正确的方法吗?打开建议。
答案 0 :(得分:14)
你的方式是要走的路(见[1])。虽然我解决了一点不同,但方法仍然类似:
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
您可以使用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)