Niy*_*yaz 0 scala dataframe apache-spark apache-spark-sql
Scala 菜鸟在这里。仍在努力学习语法。
我正在尝试减少将测试数据转换为 DataFrame 时必须编写的代码。这是我现在所拥有的:
def makeDf[T](seq: Seq[(Int, Int)], colNames: String*): Dataset[Row] = {
val context = session.sqlContext
import context.implicits._
seq.toDF(colNames: _*)
}
Run Code Online (Sandbox Code Playgroud)
问题是上述方法只需要一个形状序列Seq[(Int, Int)]作为输入。如何让它以任何序列作为输入?我可以将输入形状更改为Seq[AnyRef],但是代码无法将toDF调用识别为有效符号。
我无法弄清楚如何进行这项工作。有任何想法吗?谢谢!
简短的回答:
import scala.reflect.runtime.universe.TypeTag
def makeDf[T <: Product: TypeTag](seq: Seq[T], colNames: String*): DataFrame = ...
Run Code Online (Sandbox Code Playgroud)
解释:
当您调用 seq.toDF 时,您实际上是在使用 SQLImplicits 中定义的隐式:
implicit def localSeqToDatasetHolder[T : Encoder](s: Seq[T]): DatasetHolder[T] = {
DatasetHolder(_sqlContext.createDataset(s))
}
Run Code Online (Sandbox Code Playgroud)
这反过来又需要生成一个编码器。问题是编码器仅在某些类型上定义。特别是 Product(即元组、case 类等)您还需要添加隐式 TypeTag,以便 Scala 可以克服类型擦除(在运行时所有 Sequences 都具有类型序列,而不管泛型类型如何。TypeTag 提供了这方面的信息) .
作为侧节点,您不需要从会话中提取 sqlcontext,您可以简单地使用:
import sparkSession.implicits._
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |