К сожалению, в искре нет встроенной функции для этого.Существует решение, использующее pivot
, но вам нужно «взорвать» фрейм данных раньше.Это должно быть намного быстрее, чем ваше решение, основанное на союзах.
В scala это будет выглядеть следующим образом.Я добавил версию Java прямо ниже.
// scala
val cols = df.columns
.filter(_ != "names")
.map(n => struct(lit(n) as "c", col(n) as "v"))
val exploded_df = df.select(col("names"), explode(array(cols : _*)))
// java
Column[] cols = Arrays
.stream(df.columns())
.filter(x -> ! x.equals("names"))
.map(n -> struct(lit(n).alias("c"), col(n).alias("v")))
.toArray(Column[]::new);
Dataset<Row> exploded_df = df.select(col("names"), explode(array(cols)));
exploded_df.show();
+------+-------------+
| names| col|
+------+-------------+
| rho| [rho_0,1]|
| rho| [rho_1,0.89]|
| rho| [rho_2,0.66]|
| rho|[rho_3,0.074]|
|absRho| [rho_0,1]|
|absRho| [rho_1,0.89]|
|absRho| [rho_2,0.66]|
|absRho|[rho_3,0.074]|
| lag| [rho_0,0]|
| lag| [rho_1,1]|
| lag| [rho_2,2]|
| lag| [rho_3,3]|
+------+-------------+
По сути, я построил столбец массива, который содержит структуры, состоящие из имени столбца и его значения.Затем я использовал функцию разнесения, чтобы сгладить этот массив.Оттуда мы можем использовать pivot
как обычно; -)
// scala and java
exploded_df
.groupBy(col("col.c"))
.pivot("names")
.agg(first(col("col.v")))
.orderBy("c")
.show();
+-----+------+---+-----+
| c|absRho|lag| rho|
+-----+------+---+-----+
|rho_0| 1| 0| 1|
|rho_1| 0.89| 1| 0.89|
|rho_2| 0.66| 2| 0.66|
|rho_3| 0.074| 3|0.074|
+-----+------+---+-----+