Разбить коллекцию структур (ключ, значение) на несколько столбцов - PullRequest
0 голосов
/ 08 января 2020

У меня есть фрейм данных с одним из столбцов array<struct<key:string, value: string>>. Я хочу разбить этот столбец на несколько столбцов, где значения элементов key становятся именами этих столбцов, а значения элементов value становятся значениями этих столбцов на основе key. Может быть, картинка проиллюстрирует это лучше:

Учитывая столбец c с массивом: [[name, John], [role, admin], [created_at, 1555757657654]], я хочу иметь фрейм данных следующей структуры:

+------+-------+---------------+
| name | role  | created_at    |
+------+-------+---------------+
| John | admin | 1555757657654 |
+------+-------+---------------+

Чтобы усложнить ситуацию кроме того, разные строки столбца c могут иметь различный набор ключей, и все эти ключи должны стать столбцами, для которых в строках отсутствуют соответствующие ключи. Значение равно нулю.

PS для адресации XY Проблема , я хочу эффективно запрашивать строки на основе ключей и значений. Я пытался использовать функцию array_contains для проверки наличия ключей в массиве, но обнаружил, что производительность недостаточна.

1 Ответ

1 голос
/ 08 января 2020

Если я правильно понимаю ваше требование, вам нужно преобразование groupBy/pivot:

case class KV(key: String, value: String)

val df = Seq(
  (1, Seq(KV("name", "John"), KV("role", "admin"))),
  (2, Seq(KV("name", "Rachel"), KV("role", "user"))),
  (3, Seq(KV("name", "Dave"), KV("created_at", "1555757657654")))
).toDF("id", "kvs")

df.
  withColumn("kv", explode($"kvs")).
  groupBy($"id").pivot($"kv.key").agg(first($"kv.value")).
  show
// +---+-------------+------+-----+
// | id|   created_at|  name| role|
// +---+-------------+------+-----+
// |  1|         null|  John|admin|
// |  3|1555757657654|  Dave| null|
// |  2|         null|Rachel| user|
// +---+-------------+------+-----+
...