Spark scala полное соединение выводит ноль при присоединении столбца - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь объединить 2 кадра данных с одинаковыми именами столбцов, чтобы создать новый кадр большего размера, сохраняя все данные. Я использую coalesce для замены значений из одного кадра данных, если существует такой же идентификатор.

Соединение и объединение получается нормально, но объединяющий столбец ("id") приводит к значению null, когда идентификатор существует. Не уверен, почему:

Пример:

val tmp = Seq(
  (1,"A"),
  (2,"B"),
  (3,"A"),
  (4,"A")
).toDF("id","label")


val tmp2 = Seq(
  (1,"B"),
  (2,"B"),
  (3,"B"),
  (5, "A")
).toDF("id","label")

код:

import org.apache.spark.sql.functions._

// replace values in tmp(label) with tmp2(label) if both have same id.
val tmp3 = tmp.join(tmp2, tmp("id") === tmp2("id"), "fullouter")
           .select(tmp("id"), coalesce(tmp2("label"), tmp("label")))

output:
+----+----------------------+
|  id|coalesce(label, label)|
+----+----------------------+
|null|                     A|
|   1|                     B|
|   2|                     B|
|   3|                     B|
|   4|                     A|
+----+----------------------+

Требуется:

output:
+----+----------------------+
|  id|coalesce(label, label)|
+----+----------------------+
|   5|                     A|
|   1|                     B|
|   2|                     B|
|   3|                     B|
|   4|                     A|
+----+----------------------+

изменение объединения на "full" наш "outer" имеет тот же результат.

1 Ответ

0 голосов
/ 16 января 2020

Вы выполняете полное внешнее объединение, поэтому оно объединит все строки из обеих таблиц.

Поскольку вы используете id из tmp в качестве идентификатора результата, когда есть строка в tmp2, которое отсутствует в tmp, оно не может принимать действительное значение, поэтому оно равно нулю

Чтобы получить ожидаемый результат, вы можете использовать другой coalesce в первом столбце, так же, как вы делаете во втором

val tmp3 = tmp.join(tmp2, tmp("id") === tmp2("id"), "fullouter")
.select(coalesce(tmp("id"), tmp2("id")), coalesce(tmp2("label"), tmp("label")))
+----------------+----------------------+
|coalesce(id, id)|coalesce(label, label)|
+----------------+----------------------+
|               1|                     B|
|               3|                     B|
|               5|                     A|
|               4|                     A|
|               2|                     B|
+----------------+----------------------+
...