如何将RDD [(String,Any)]转换为Array(Row)?

时间:2017-09-29 08:48:22

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

我有一个带有键和值的非结构化RDD。值为RDD [Any],键当前为Strings,RDD [String],主要包含Maps。我想让它们成为Row类型,这样我最终可以创建一个数据帧。这是我的rdd:

除去

除了最后4个键之外,大多数rdd都遵循一个模式,应该如何处理?也许将它们分成自己的rdd,特别是对于reverseDeltas?

由于

修改

根据下面的第一个答案,到目前为止我已经累了。

case class MyData(`type`: List[String], libVersion: Double, id: BigInt)

object MyDataBuilder{
    def apply(s: Any): MyData = {
      // read the input data and convert that to the case class

      s match {
        case Array(x: List[String], y: Double, z: BigInt) => MyData(x, y, z)
        case Array(a: BigInt, Array(x: List[String], y: Double, z: BigInt)) => MyData(x, y, z)
        case _ => null
      }
    }
  }

val parsedRdd: RDD[MyData] = rdd.map(x => MyDataBuilder(x))

它是如何看待匹配任何这些情况的,我如何匹配scala中的Map?打印出null

时,我不断回复parsedRdd

2 个答案:

答案 0 :(得分:0)

要将RDD转换为数据帧,您需要具有固定架构。如果为RDD定义模式,则休息很简单。

类似

val rdd2:RDD[Array[String]] = rdd.map( x => getParsedRow(x)) 
val rddFinal:RDD[Row] = rdd2.map(x => Row.fromSeq(x))

替代

case class MyData(....) // all the fields of the Schema I want
object MyDataBuilder {
  def apply(s:Any):MyData ={
    // read the input data and convert that to the case class
  }
}

val rddFinal:RDD[MyData] = rdd.map(x => MyDataBuilder(x))
import spark.implicits._
val myDF = rddFinal.toDF

答案 1 :(得分:0)

有一种将rdd转换为数据帧的方法 像下面一样使用它

val rdd = sc.textFile("/pathtologfile/logfile.txt")
val df = rdd.toDF()

没有数据框使用下面的SQL查询

执行您想要的任何操作
val textFile = sc.textFile("hdfs://...")
// Creates a DataFrame having a single column named "line"
val df = textFile.toDF("line")
val errors = df.filter(col("line").like("%ERROR%"))
// Counts all the errors
errors.count()
// Counts errors mentioning MySQL
errors.filter(col("line").like("%MySQL%")).count()
// Fetches the MySQL errors as an array of strings
errors.filter(col("line").like("%MySQL%")).collect()