Сопоставить мультикарту со столбцами данных - PullRequest
0 голосов
/ 17 октября 2018

Просто я хочу преобразовать мультикарту следующим образом:

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  |
+-------+--------------+-------+

заменив отсутствующие значения на "нулевые" значения.Моя проблема заключается в применении функции карты к СДР:

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

Есть предложения?Заранее спасибо

1 Ответ

0 голосов
/ 17 октября 2018

Хотя, смотрите мои комментарии, я действительно не уверен, что формат мультикарты хорошо подходит для вашей проблемы (вы смотрели на Модули разбора Spark XML ?)

решение сводной таблицы

Идея состоит в том, чтобы сгладить входную таблицу в формате (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|
+----------+------+------+

Возможно, это не лучшее решение, но оно полностью масштабируемо для любого количества столбцов.

...