Вот один подход, использующий тип scala Map
для создания сопоставлений столбцов с использованием следующего набора данных:
val data = Seq(
(1, 23, 1, 0, 2, 0),
(2, 23, 0, 1, 0, 1),
(2, 29, 1, 0, 1, 0)).toDF("ID", "ID-2", "count(apple)", "count(banana)", "count(potato)", "count(onion)")
Сначала мы объявляем сопоставления, используя scala.collection.immutable.Map
collection и функцию, которая отвечает за сопоставление:
import org.apache.spark.sql.{Column, DataFrame}
val colMapping = Map(
"count(banana)" -> "no of banana",
"count(apple)" -> "no of apples",
"count(potato)" -> "no of potatos",
"count(onion)" -> "no of onions")
def mapColumns(colsMapping: Map[String, String], df: DataFrame) : DataFrame = {
val mapping = df
.columns
.map{ c => if (colsMapping.contains(c)) df(c).alias(colsMapping(c)) else df(c)}
.toList
df.select(mapping:_*)
}
Функция выполняет итерации по столбцам данного кадра данных и идентифицирует столбцы, имеющие общие ключи, с mapping
. Затем он возвращает столбец, меняющий свое имя (с псевдонимом) в соответствии с примененными сопоставлениями.
Выход mapColumns(colMapping, df).show(false)
:
+---+----+------------+------------+-------------+------------+
|ID |ID-2|no of apples|no of banana|no of potatos|no of onions|
+---+----+------------+------------+-------------+------------+
|1 |23 |1 |0 |2 |0 |
|2 |23 |0 |1 |0 |1 |
|2 |29 |1 |0 |1 |0 |
+---+----+------------+------------+-------------+------------+
Наконец, мы производим фрукты и овощи с помощью struct
типа:
df1.withColumn("fruits", struct(col(colMapping("count(banana)")), col(colMapping("count(apple)"))))
.withColumn("vegetables", struct(col(colMapping("count(potato)")), col(colMapping("count(onion)"))))
.drop(colMapping.values.toList:_*)
.toJSON
.show(false)
Обратите внимание, что мы отбрасываем все столбцы коллекции colMapping после завершения преобразований.
Выход:
+-----------------------------------------------------------------------------------------------------------------+
|value |
+-----------------------------------------------------------------------------------------------------------------+
|{"ID":1,"ID-2":23,"fruits":{"no of banana":0,"no of apples":1},"vegetables":{"no of potatos":2,"no of onions":0}}|
|{"ID":2,"ID-2":23,"fruits":{"no of banana":1,"no of apples":0},"vegetables":{"no of potatos":0,"no of onions":1}}|
|{"ID":2,"ID-2":29,"fruits":{"no of banana":0,"no of apples":1},"vegetables":{"no of potatos":1,"no of onions":0}}|
+-----------------------------------------------------------------------------------------------------------------+