【问题标题】:Write List of Map data into csv将地图数据列表写入csv
【发布时间】:2024-05-02 12:40:02
【问题描述】:
val rdd = df.rdd.map(line => Row.fromSeq((
        scala.xml.XML.loadString("<?xml version='1.0' encoding='utf-8'?>" + line(1)).child
        .filter(elem =>
               elem.label == "name1" 
            || elem.label == "name2" 
            || elem.label == "name3"  
            || elem.label == "name4" 

        ).map(elem => (elem.label -> elem.text)).toList)
    )

我是rdd.take(10).foreach(println),我是RDD[Row] 然后产生如下输出:

[(name1, value1), (name2, value2),(name3, value3)]
[(name1, value11), (name2, value22),(name3, value33)]
[(name1, value111), (name2, value222),(name4, value44)]

我想用 (name1..name4 是 csv 的标题) 将它保存到 csv 中,请任何人帮助我如何用 apache spark 2.4.0 实现它

name1    | name2     | name3    | name4
value1   | value2    |value3    | null
value11  | value22   |value33   | null
value111 | value222  |null      | value444

【问题讨论】:

    标签: scala apache-spark scala-xml


    【解决方案1】:

    我调整了您的示例并添加了一些中间值来帮助完成每个步骤:

      // define the labels you want:
      val labels = Seq("name1", "name2", "name3", "name4")
      val result: RDD[Row] = rdd.map { line =>
        // your raw data
        val tuples: immutable.Seq[(String, String)] = 
          scala.xml.XML.loadString("<?xml version='1.0' encoding='utf-8'?>" + line(1)).child
          .filter(elem => labels.contains(elem.label)) // you can use the label list to filter
          .map(elem => (elem.label -> elem.text)).toList // no change here
        val values: Seq[String] = 
        labels.map(l =>
          // take the values you have a label 
          tuples.find{case (k, v) => k == l}.map(_._2)
          // or just add an empty String
            .getOrElse(""))
        // create a Row
        Row.fromSeq(values)
      }
    

    现在我不确定 - 但本质上你必须将标题 Row 作为第一行插入:

    [name1, name2, name3]
    

    【讨论】:

    • 这是不对的,因为当xml中缺少例如name1时,我们将如何处理,标题和数据行如何保持一致?您能帮忙提供完整的解决方案吗?
    • 看看我的新答案 - 希望能让你更接近;)
    • 感谢您的回复。我真的很感激。但是我找到了将其转换为 json 数据集然后写入 csv 的解决方案,因此表头将相应地工作。