【问题标题】:How to create DataFrame from Scala's List of Iterables?如何从 Scala 的 Iterables 列表中创建 DataFrame?
【发布时间】:2016-10-30 00:18:22
【问题描述】:

我有以下 Scala 值:

val values: List[Iterable[Any]] = Traces().evaluate(features).toList

我想将其转换为 DataFrame。

当我尝试以下操作时:

sqlContext.createDataFrame(values)

我收到了这个错误:

error: overloaded method value createDataFrame with alternatives:

[A <: Product](data: Seq[A])(implicit evidence$2: reflect.runtime.universe.TypeTag[A])org.apache.spark.sql.DataFrame 
[A <: Product](rdd: org.apache.spark.rdd.RDD[A])(implicit evidence$1: reflect.runtime.universe.TypeTag[A])org.apache.spark.sql.DataFrame
cannot be applied to (List[Iterable[Any]])
          sqlContext.createDataFrame(values)

为什么?

【问题讨论】:

  • List[Iterable[Any]]?你没有。如果值可以使用 SQL 类型表示,则转换为 List[Row] 并提供架构。

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


【解决方案1】:

这就是 spark 隐含对象的用途。它允许您将常见的 scala 集合类型转换为 DataFrame / DataSet / RDD。 这是 Spark 2.0 的示例,但它也存在于旧版本中

import org.apache.spark.sql.SparkSession
val values = List(1,2,3,4,5)

val spark = SparkSession.builder().master("local").getOrCreate()
import spark.implicits._
val df = values.toDF()

编辑:刚刚意识到你是在二维列表之后。这是我在 spark-shell 上尝试过的东西。我将二维列表转换为元组列表,并使用隐式转换为 DataFrame:

val values = List(List("1", "One") ,List("2", "Two") ,List("3", "Three"),List("4","4")).map(x =>(x(0), x(1)))
import spark.implicits._
val df = values.toDF

Edit2:MTT 的原始问题是如何从 Scala 列表中为 2d 列表创建火花数据帧,这是正确答案。原来的问题是https://stackoverflow.com/revisions/38063195/1 该问题后来被更改以匹配已接受的答案。添加此编辑,以便其他人在寻找与原始问题类似的内容时可以找到它。

【讨论】:

  • 好答案,我不知道可以直接将列表转换为数据帧(我认为我们应该先创建一个 RDD)。这在单元测试中非常有用。 +1
  • 如何修改异构列类型,即 List(List(1, "One") ,List(2, "Two") ,List(3, "Three"),List (4,"四"))?
  • @SarahMesser 您最好从元组列表开始,而不是从列表列表开始。当您将列表列表转换为元组列表时,或者不太优雅,您可以将元组的每个元素转换为类型,例如.map(x =&gt;(x(0).asInstanceOf[Int], x(1).asInstanceOf[String]))类型为scala.Any时,spark无法知道应该转换成什么列类型
  • 问题明显不同。
【解决方案2】:

正如zero323 提到的,我们需要先将List[Iterable[Any]] 转换为List[Row],然后将行放入RDD 并为spark 数据帧准备架构。

要将List[Iterable[Any]] 转换为List[Row],我们可以说

val rows = values.map{x => Row(x:_*)}

然后有了schema这样的模式,我们就可以制作RDD了

val rdd = sparkContext.makeRDD[RDD](rows)

最后创建一个 spark 数据框

val df = sqlContext.createDataFrame(rdd, schema)

【讨论】:

  • 我猜你的意思是sparkContext.makeRDD[Row](rows)
  • makeRDD[Row] 会出错,val rdd = sparkContext.makeRDD(rows) 对我来说很好。
【解决方案3】:

最简单的方法:

val newList = yourList.map(Tuple1(_))
val df = spark.createDataFrame(newList).toDF("stuff")

【讨论】:

    【解决方案4】:

    在 Spark 2 中,我们可以通过 toDS API 将列表转换为 DS 来使用 DataSet

    val ds = list.flatMap(_.split(",")).toDS() // Records split by comma 
    

    val ds = list.toDS()
    

    这比rdddf 更方便

    【讨论】:

    • toDF() 不对 List[List[Any]] 进行操作
    【解决方案5】:

    我找到的最简洁的方法:

    val df = spark.createDataFrame(List("A", "B", "C").map(Tuple1(_)))
    

    【讨论】:

    • 这对我有用!用于映射到 DF.. spark.createDataFrame(myMap.toList.map(e =&gt; Tuple2(e._1, e._2))).toDF("col1", "col1")
    猜你喜欢
    • 2020-09-22
    • 2019-08-31
    • 2019-11-24
    • 1970-01-01
    • 2017-03-07
    • 2015-01-17
    • 2016-08-14
    • 2015-03-09
    • 1970-01-01
    相关资源
    最近更新 更多