Scala - Условная замена значения столбца фрейма данных - PullRequest
0 голосов
/ 24 августа 2018

DataFrame 1 - это то, что у меня есть сейчас, и я хочу написать функцию Scala, чтобы DataFrame 1 выглядел как DataFrame 2.

Перевод большой категории; Электронный перевод и IMT являются подкатегориями.

Логика заключается в том, что для одного и того же идентификатора (31898), если к нему привязаны как Transfer, так и e-Transfer, это должен быть только e-Transfer; если Transfer и IMT и e-Transfer все помечены одним и тем же идентификатором (32614), это должен быть e-Transfer + IMT; Если только Передача помечена одним идентификатором (33987), это должно быть Другое; если только e-Transfer или IMT помечены идентификатором (34193), то это должен быть только электронный перевод IMT.

Впервые в scala, не знаю, как написать хорошую функцию для этого. Пожалуйста, помогите !!

DataFrame 1                        DataFrame 2
+---------+-------------+          +---------+------------------+
|   ID    | Category    |          |   ID    | Category         |
+---------+-------------+          +---------+------------------+  
|  31898  |   Transfer  |          |  31898  |  e-Transfer      |  
|  31898  |  e-Transfer |          |  32614  |  e-Transfer + IMT|
|  32614  |   Transfer  |  =====>  |  33987  |   Other          |
|  32614  |  e-Transfer |  =====>  |  34193  |  e-Transfer      |
|  32614  |     IMT     |          +---------+------------------+
|  33987  |   Transfer  |  
|  34193  |  e-Transfer |  
+---------+-------------+

1 Ответ

0 голосов
/ 24 августа 2018

Вы можете сгруппировать DataFrame по ID для агрегирования Category, используя collect_set, чтобы собрать массивы категорий, и создать новый столбец на основе содержимого в массивах категорий, используя array_contains:

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

val df = Seq(
  (31898, "Transfer"),
  (31898, "e-Transfer"),
  (32614, "Transfer"),
  (32614, "e-Transfer"),
  (32614, "IMT"),
  (33987, "Transfer"),
  (34193, "e-Transfer")
).toDF("ID", "Category")

df.groupBy("ID").agg(collect_set("Category").as("CategorySet")).
  withColumn( "Category",
    when(array_contains($"CategorySet", "e-Transfer") && array_contains($"CategorySet", "IMT"),
      "e-Transfer + IMT").otherwise(
    when(array_contains($"CategorySet", "e-Transfer") && array_contains($"CategorySet", "Transfer"),
      "e-Transfer").otherwise(
    when($"CategorySet" === Array("e-Transfer") || $"CategorySet" === Array("MIT"),
      $"CategorySet"(0)).otherwise(
    when($"CategorySet" === Array("Transfer"), "Other")
    )))
  ).
  show(false)
// +-----+---------------------------+----------------+
// |ID   |CategorySet                |Category        |
// +-----+---------------------------+----------------+
// |33987|[Transfer]                 |Other           |
// |32614|[Transfer, e-Transfer, IMT]|e-Transfer + IMT|
// |34193|[e-Transfer]               |e-Transfer      |
// |31898|[Transfer, e-Transfer]     |e-Transfer      |
// +-----+---------------------------+----------------+

Возможно, ваши данные выборки не охватывали все случаи (например, [Transfer, MIT]). Существующий пример кода будет генерировать значение категории null для любых оставшихся случаев. Просто измените / разверните условную проверку, если выявлены дополнительные случаи.

...