我想将表的某些列转置为行。我正在使用Java和Spark 2.1.2。这是我的桌子:

+-----+-----+-----+-----+-----+
|  A  |col_1|col_2|col_3|col_4|
+-----+-----------------+------+
|  1  |  0.0|  0.6|  0.8| 0.9|
|  2  |  0.6|  0.7|  0.7| 1.2|
|  3  |  0.5|  0.9|  1.8| 9.1|
|  ...|  ...|  ...|  ...| ...|


我想要这样的东西:

+-----+--------+-----------+
|  A  | col_id | col_value |
+-----+--------+-----------+
|  1  |   col_1|        0.0|
|  1  |   col_2|        0.6|
|  1  |   col_3|        0.8|
| ... |    ... |        ...|
|  2  |   col_1|        0.6|
|  2  |   col_2|        0.7|
|  ...|     ...|        ...|
|  3  |   col_1|        0.5|
|  3  |   col_2|        0.9|
|  ...|     ...|        ...| and so on


有人知道我能做到吗?我知道该解决方案适用于Python,但我正在尝试使用Java来实现。

我尝试过这种方法

 df.selectExpr("stack(4, 'col_1', col_1, 'col_2', col_2', col_3', col_3,'col_4', col_4)as (Key,Value)");


但是它不起作用。

编辑:

我能够使用上述方法获得结果。事实证明,我使用的是SparkContext而不是SQLContext,它可以完美地工作。

最佳答案

通过使用Spark-scala解决方案:

def transpose(spark: SparkSession, df: DataFrame, transposeUsing: Seq[String]): DataFrame = {
import spark.implicits._
val (cols, types) = df.dtypes.filter{ case (c, _) => !transposeUsing.contains(c)}.unzip

val kvdf = explode(array(cols.map(c => struct(lit(c).alias("column_name"),col(c).alias("column_value"))): _*))

val constantCols = transposeUsing.map(col(_))

df.select(constantCols :+ kvdf.alias("_kvdf"): _*)
  .select(constantCols ++ Seq($"_kvdf.column_name", $"_kvdf.column_value"): _*)
}
 //call the function
transpose(df, Seq("A")).show()

09-12 16:16