java - 如何在 Java Spark 中将列转置为行
问题描述
我想将表格的某些列转置为行。我正在使用 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()
推荐阅读
- r - 从不同的 html 文件创建唯一文件名时出现问题
- ios - 动画文本字段像 Messenger 和 Whatsapp 一样扩展
- python - 如何从Python中的字符串中获取两个特定字符之间的一段字符串
- python - django 查询没有正确分组
- c++ - 有必要使用std::move吗?这不是已经是右值引用了吗?
- r - 如何使用另一个数据框中的字段值调用包含列的值
- visual-studio-2015 - 我的 android 设备没有在 Visual Studio 2015 上检测到 xamarin 表单
- java - java.lang.IndexOutOfBoundsException 在不应该达到索引时嵌套for循环
- shell - 如何单击 Xpath 元素并使用 shell 脚本下载 csv 文档?
- python - 如何在 Boto3 中正确创建和附加 ELB