Простой подход только от загруженного DF.
- Явное именование столбцов, но может быть динамическим с (_) и т. Д.
- Те же типы.
- Необходимо оценить, как обрабатываются ваши нулевые значения.
- Обрабатывает любой формат данных, который вы можете использовать в общем.
Вот некоторые вкусности с парой приемов, но не перегружающие новичка, как это было:
import org.apache.spark.sql._
import org.apache.spark.sql.functions._
import spark.implicits._
val colAggList = List("a", "b", "c", "d")
val dropCols = Seq("a", "b", "c", "d")
val convToString = udf((arr: Seq[String]) => arr.mkString(",")) // Could just get the 1st element via data.withColumn("newcolname", $"colname"(0))
val df = sc.parallelize(Seq(
("r1", Some(1), Some(1), None, Some("x")),
("r1", None, None, Some(3), None),
("r2", Some(6), Some(4), None, Some("y")),
("r3", None, Some(1), Some(5), Some("abc")),
("r3", Some(4), None, None, None),
("r4", Some(1), None, None, None),
("r4", None, Some(2), None, None),
("r4", None, None, Some(3), None),
("r4", None, None, None, Some("xyz")),
("r5", Some(1), Some(2), Some(7), Some("A"))
)).toDF("ID", "a", "b", "c", "d")
df.show(false)
df.printSchema()
// Note Nones, nulls are not collected.
val df2 = df.groupBy("ID").agg( collect_list(colAggList(0)).as("a"), collect_list(colAggList(1)).as("b"), collect_list(colAggList(2)).as("c"), collect_list(colAggList(3)).as("d") )
df2.show(false)
df2.printSchema()
val df3 = df2.withColumn("aStr", convToString($"a")).withColumn("bStr", convToString($"b")).withColumn("cStr", convToString($"c")).withColumn("dStr", convToString($"d")).drop(dropCols:_*)
df3.show(false)
df3.printSchema()
возвращается, и поэтому вы можете видеть, как это работает - только показывается исходный и окончательный результат:
+---+----+----+----+----+
|ID |a |b |c |d |
+---+----+----+----+----+
|r1 |1 |1 |null|x |
|r1 |null|null|3 |null|
|r2 |6 |4 |null|y |
|r3 |null|1 |5 |abc |
|r3 |4 |null|null|null|
|r4 |1 |null|null|null|
|r4 |null|2 |null|null|
|r4 |null|null|3 |null|
|r4 |null|null|null|xyz |
|r5 |1 |2 |7 |A |
+---+----+----+----+----+
+---+----+----+----+----+
|ID |aStr|bStr|cStr|dStr|
+---+----+----+----+----+
|r1 |1 |1 |3 |x |
|r5 |1 |2 |7 |A |
|r2 |6 |4 | |y |
|r4 |1 |2 |3 |xyz |
|r3 |4 |1 |5 |abc |
+---+----+----+----+----+
Обратите внимание на придуманное пропущенное значение, показанное как пустое.