将多图映射到数据框的列

时间:2018-10-17 10:00:50

标签: scala apache-spark dataframe rdd

简而言之,我想像这样转换多图:

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()

有什么建议吗?预先感谢

1 个答案:

答案 0 :(得分:0)

尽管看到我的评论,但我真的不确定多图格式是否适合您的问题(您是否看过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|
+----------+------+------+

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