[英]Pass case class to Spark UDF
我有一個scala-2.11函數,該函數根據提供的類類型從Map創建一個案例類。
def createCaseClass[T: TypeTag, A](someMap: Map[String, A]): T = {
val rMirror = runtimeMirror(getClass.getClassLoader)
val myClass = typeOf[T].typeSymbol.asClass
val cMirror = rMirror.reflectClass(myClass)
// The primary constructor is the first one
val ctor = typeOf[T].decl(termNames.CONSTRUCTOR).asTerm.alternatives.head.asMethod
val argList = ctor.paramLists.flatten.map(param => someMap(param.name.toString))
cMirror.reflectConstructor(ctor)(argList: _*).asInstanceOf[T]
}
我試圖在Spark數據框架的上下文中將其用作UDF。 但是,我不確定傳遞案例類的最佳方法是什么。 下面的方法似乎不起作用。
def myUDF[T: TypeTag] = udf { (inMap: Map[String, Long]) =>
createCaseClass[T](inMap)
}
我正在尋找這樣的東西-
case class MyType(c1: String, c2: Long)
val myUDF = udf{(MyType, inMap) => createCaseClass[MyType](inMap)}
提出了解決該問題的想法和建議。
但是,我不確定通過案例類的最佳方法是什么
案例類不能用作用戶定義函數的參數。 SQL StructTypes
映射到動態類型(缺少更好的詞)的Row
對象。
如果要對靜態類型的對象進行操作,請使用靜態類型的Dataset
。
通過反復試驗,我了解到,存儲在數據框或數據集中的任何數據結構都在使用org.apache.spark.sql.types
您可以看到:
df.schema.toString
基本類型(如Int,Double)的存儲方式如下:
StructField(fieldname,IntegerType,true),StructField(fieldname,DoubleType,true)
諸如case類之類的復雜類型將轉換為嵌套類型的組合:
StructType(StructField(..),StructField(..),StructType(..))
樣例代碼:
case class range(min:Double,max:Double)
org.apache.spark.sql.Encoders.product[range].schema
//Output:
org.apache.spark.sql.types.StructType = StructType(StructField(min,DoubleType,false), StructField(max,DoubleType,false))
在這種情況下,當您存儲案例類數組時,UDF參數類型為Row或Seq [Row]
基本的調試技術打印到字符串:
val myUdf = udf( (r:Row) => r.schema.toString )
然后,看看發生了什么:
df.take(1).foreach(println) //
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.