在Scala / Spark 1.6中将多个输入文件加载到一个Dataframe中

时间:2016-10-10 17:44:05

标签: scala dataframe

我正在尝试将多个输入文件加载到单个数据框中:

val inputs = List[String]("input1.txt", "input2.txt", "input3.txt")

val dataFrames = for (
  i  <- inputs;
  df <- sc.textFile(i).toDF()
) yield {df}

val inputDataFrame = unionAll(dataFrames, sqlContext)

// union of all given DataFrames
private def unionAll(dataFrames: Seq[DataFrame], sqlContext: SQLContext): DataFrame = dataFrames match {
  case Nil => sqlContext.emptyDataFrame
  case head :: Nil => head
  case head :: tail => head.unionAll(unionAll(tail, sqlContext))
}

编译说

Error:(40, 8) type mismatch;
 found   : org.apache.spark.rdd.RDD[org.apache.spark.sql.Row]
 required: scala.collection.GenTraversableOnce[?]
    df <- sc.textFile(i).toDF()
       ^

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

首先,SQLContext.read.text(...)接受多个文件名参数,因此您只需执行:

val inputs = List[String]("input1.txt", "input2.txt", "input3.txt")
val inputDataFrame = sqlContext.read.text(inputs: _*)

或者:

val inputDataFrame = sqlContext.read.text("input1.txt", "input2.txt", "input3.txt")

至于你的代码 - 你写的时候:

val dataFrames = for (
  i  <- inputs;
  df <- sc.textFile(i).toDF()
) yield df

它被翻译成:

inputs.flatMap(i => sc.textFile(i).toDF().map(df => df))

哪个无法编译,因为flatMap需要一个返回GenTraversableOnce[?]的函数,而提供的函数返回RDD[Row](参见DataFrame.map的签名) 。换句话说,当您编写df <- sc.textFile(i).toDF()时,您实际上正在对数据框中的每个进行处理,并产生一个新的RDD这些行,这些行不是{&lt;}}。你的意图。

你想做的事情比较简单:

val dataFrames = for (
  i  <- inputs;
) yield sc.textFile(i).toDF()

但是,正如开头所提到的,推荐的方法是使用sqlContext.read.text