Spark DataFrame:将 144 列转换为行
Spark DataFrame: converting 144 columns into row
环境:Spark 2.4.0;斯卡拉
我已经从具有 144 列的 CSV 创建了 DF。有没有办法把除一列以外的所有列都改成行?
Table A
|dt |AA|BB|CC|
|----|--|--|--|
|1012|10|12|13|
|1013|13|14|15|
|1014|14|18|30|
Table B (After transform Table A)
|dt |Head|Val|
|----|----|---
|1012|AA |12|
|1013|AA |13|
|1014|AA |14|
|1012|BB |12|
|1013|BB |14|
|1014|BB |18|
|1012|CC |13|
|1013|CC |15|
|1014|CC |30|
我需要转置/UnPivot table A 到 Table B。请注意,Table A 有 144 列。我以为内置函数 stack(n, expr1, ..., exprk) 但我不知道如何自动传递这么多列。
感谢您花时间和精力提供帮助。
问题的答案是如何自动处理 DF 中的所有列。
val columnsToConcat: Array[String] = df.schema.fieldNames.filter(_ == "yourSingleColToExclude")
df.select("yourSingleColToExclude", concat_ws("separator", columnsToConcat.map(col):_*))
但是我不知道,关于 stack
函数的限制。
您可以使用 Scala 字符串操作为 stack 动态创建参数列表:
val dfA = Seq((1012, 10, 12, 13), (1013, 13, 14, 15), (1014, 14, 18, 30)).toDF("dt", "AA", "BB", "CC")
val columns = dfA.columns.filter(!_.equalsIgnoreCase("dt"))
var cmd = s"stack(${columns.length},"
for( col <- columns) cmd += s"'$col',$col,"
cmd = cmd.dropRight(1) + ")"
val dfB = dfA.selectExpr("dt", cmd)
.withColumnRenamed("col0", "Head")
.withColumnRenamed("col1", "Val")
结果:
+----+----+---+
| dt|Head|Val|
+----+----+---+
|1012| AA| 10|
|1012| BB| 12|
|1012| CC| 13|
|1013| AA| 13|
|1013| BB| 14|
|1013| CC| 15|
|1014| AA| 14|
|1014| BB| 18|
|1014| CC| 30|
+----+----+---+
环境:Spark 2.4.0;斯卡拉
我已经从具有 144 列的 CSV 创建了 DF。有没有办法把除一列以外的所有列都改成行?
Table A
|dt |AA|BB|CC|
|----|--|--|--|
|1012|10|12|13|
|1013|13|14|15|
|1014|14|18|30|
Table B (After transform Table A)
|dt |Head|Val|
|----|----|---
|1012|AA |12|
|1013|AA |13|
|1014|AA |14|
|1012|BB |12|
|1013|BB |14|
|1014|BB |18|
|1012|CC |13|
|1013|CC |15|
|1014|CC |30|
我需要转置/UnPivot table A 到 Table B。请注意,Table A 有 144 列。我以为内置函数 stack(n, expr1, ..., exprk) 但我不知道如何自动传递这么多列。
感谢您花时间和精力提供帮助。
问题的答案是如何自动处理 DF 中的所有列。
val columnsToConcat: Array[String] = df.schema.fieldNames.filter(_ == "yourSingleColToExclude")
df.select("yourSingleColToExclude", concat_ws("separator", columnsToConcat.map(col):_*))
但是我不知道,关于 stack
函数的限制。
您可以使用 Scala 字符串操作为 stack 动态创建参数列表:
val dfA = Seq((1012, 10, 12, 13), (1013, 13, 14, 15), (1014, 14, 18, 30)).toDF("dt", "AA", "BB", "CC")
val columns = dfA.columns.filter(!_.equalsIgnoreCase("dt"))
var cmd = s"stack(${columns.length},"
for( col <- columns) cmd += s"'$col',$col,"
cmd = cmd.dropRight(1) + ")"
val dfB = dfA.selectExpr("dt", cmd)
.withColumnRenamed("col0", "Head")
.withColumnRenamed("col1", "Val")
结果:
+----+----+---+
| dt|Head|Val|
+----+----+---+
|1012| AA| 10|
|1012| BB| 12|
|1012| CC| 13|
|1013| AA| 13|
|1013| BB| 14|
|1013| CC| 15|
|1014| AA| 14|
|1014| BB| 18|
|1014| CC| 30|
+----+----+---+