【问题标题】:Map a multimap to columns of dataframe将多图映射到数据框的列
【发布时间】:2019-03-21 23:19:28
【问题描述】:

简单地说,我想像这样转换多图:

val input = Map("rownum"-> List("1", "2", "3") ,  "plant"-> List( "Melfi", "Pomigliano", "Torino" ), "tipo"-> List("gomme", "telaio")).toArray

在以下 Spark 数据帧中:

+-------+--------------+-------+
|rownum |   plant      | tipo  |
+------ +--------------+-------+
| 1     |   Melfi      | gomme |
| 2     |   Pomigliano | telaio|
| 3     |   Torino     | null  |
+-------+--------------+-------+

用“空”值替换缺失值。我的问题是将地图功能应用于 RDD:

val inputRdd = sc.parallelize(input)
inputRdd.map(..).toDF()

有什么建议吗?提前致谢

【问题讨论】:

  • 你怎么知道缺少的“tipo”值是rownum 3 的值?它可能来自任何地方,除非您有理由知道缺失值只能来自“截断”列表。
  • 因为列名是按顺序提取的XML标签。所以假设你有以下 xml: 1 Melfigomme 2 Pomiglianotelaio 3 Torino 。正如你所看到的植物 Torino hano "tipo",所以我想用 "null" 替换那个缺失的值。
  • 感谢您的回复。您可以编辑您的问题以添加这些相关信息,这对于未来的读者来说更具可读性。
  • XML 告诉我 rownum 3 没有“错字”,但多图不允许我得出这个结论。采用相同的 XML,但从 rownum 2 中删除 tipo 并将其放入 rownum 3,您将获得相同的多图。您的 XML to Map 似乎破坏了关于 null 来自何处的重要信息。

标签: scala apache-spark dataframe rdd


【解决方案1】:

虽然,请参阅我的 cmets,但我真的不确定多地图格式是否适合您的问题(您看过 Spark XML parsing modules 吗?)

数据透视表解决方案

这个想法是将您的输入表展平为(elementPosition, columnName, columnValue) 格式:

// The max size of the multimap lists
val numberOfRows = input.map(_._2.size).max
// For each index in the list, emit a tuple of (index, multimap key, multimap value at index)
val flatRows = (0 until numberOfRows).flatMap(rowIdx => input.map({ case (colName, allColValues) => (rowIdx, colName, if(allColValues.size > rowIdx) allColValues(rowIdx) else null)}))
// Probably faster at runtime to write it this way (less iterations) : 
// val flatRows = input.flatMap({ case (colName, existingValues) => (0 until numberOfRows).zipAll(existingValues, null, null).map(t => (t._1.asInstanceOf[Int], colName, t._2)) })
// To dataframe
val flatDF = sc.parallelize(flatRows).toDF("elementIndex", "colName", "colValue")
flatDF.show

将输出:

+------------+-------+----------+
|elementIndex|colName|  colValue|
+------------+-------+----------+
|           0| rownum|         1|
|           0|  plant|     Melfi|
|           0|   tipo|     gomme|
|           1| rownum|         2|
|           1|  plant|Pomigliano|
|           1|   tipo|    telaio|
|           2| rownum|         3|
|           2|  plant|    Torino|
|           2|   tipo|      null|
+------------+-------+----------+

现在这是一个数据透视表问题:

flatDF.groupBy("elementIndex").pivot("colName").agg(expr("first(colValue)")).drop("elementIndex").show
+----------+------+------+
|     plant|rownum|  tipo|
+----------+------+------+
|Pomigliano|     2|telaio|
|    Torino|     3|  null|
|     Melfi|     1| gomme|
+----------+------+------+

这可能不是最好看的解决方案,但它可以完全扩展到任意数量的列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多