Невозможно сгруппировать столбец MapType в Spark DataFrame - PullRequest
3 голосов
/ 13 мая 2019

Моя текущая проблема следующая ...

Exception in thread "main" org.apache.spark.sql.AnalysisException: expression 'mapField' cannot be used as a grouping expression because its data type map<string,string> is not an orderable data type.;;

То, чего я пытаюсь добиться, - это просто группировать записи внутри DataFrame по заданному набору столбцов, но, похоже, происходит сбой при группировании со столбцами MapType, такими как упоминалось ранее.

  .groupBy(
    ...
    "mapField",
    ...
  )

У меня есть пара идей, но должно быть более простое решение этой проблемы, чем следующие, о которых я думал ...

  • У меня есть ключ, значение каждого из элементов, сохраненных в объединенной строке в DF, так что я мог бы, возможно, проанализировать их в Map и затем сохранить, используя withColumn, но не нашел какой-то подход, и я тоже не смог заставить работать. Это разумно сделать?

  • Перегруппировать в RDD и сгруппировать его там, затем обратно в DF (слишком много хлопот, я думаю)

EDIT

Пример ввода

   id    |  myMap
'sample' |  Map('a' -> 1, 'b' -> 2, 'c' -> 3)

желаемый выход

   id    |  a  |  b  |  c
'sample' |  1  |  2  |  3

1 Ответ

2 голосов
/ 13 мая 2019

Вы можете использовать map_values и map_keys следующим образом:

import org.apache.spark.sql.functions.{map_values, map_keys}
val df = Seq(
    (Map("k1"->"v1"), 12),
    (Map("k2"->"v2"), 11),
    (null, 10) 
).toDF("map", "id")

df.select(map_values($"map")).show

// +---------------+
// |map_values(map)|
// +---------------+
// |           [v1]|
// |           [v2]|
// |           null|
// +---------------+

df.select(map_keys($"map")).show

// +-------------+
// |map_keys(map)|
// +-------------+
// |         [k1]|
// |         [k2]|
// |         null|
// +-------------+

df.withColumn("key", map_keys($"map").getItem(0)).show

// +----------+---+----+
// |       map| id| key|
// +----------+---+----+
// |[k1 -> v1]| 12|  k1|
// |[k2 -> v2]| 11|  k2|
// |      null| 10|null|
// +----------+---+----+

Или напрямую с groupBy:

df.groupBy(map_keys($"map").getItem(0)).count()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...