我正在尝试将多个输入文件加载到单个数据框中:
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()
^
有什么想法吗?
答案 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
。