为什么总和在聚合和数据透视后不显示?

Why sum is not displaying after aggregation & pivot?

我这里有如下学生分数,我想转置学科名称列并希望在数据透视之后也获得总分。

来源table喜欢:

+---------+-----------+-----+
|StudentId|SubjectName|Marks|
+---------+-----------+-----+
|        1|          A|   10|
|        1|          B|   20|
|        1|          C|   30|
|        2|          A|   20|
|        2|          B|   25|
|        2|          C|   30|
|        3|          A|   10|
|        3|          B|   20|
|        3|          C|   20|
+---------+-----------+-----+

Destination:
+---------+---+---+---+-----+
|StudentId|  A|  B|  C|Total|
+---------+---+---+---+-----+
|        1| 10| 20| 30|   60|
|        3| 10| 20| 20|   50|
|        2| 20| 25| 30|   75|
+---------+---+---+---+-----+

请找到以下源代码:

val spark = SparkSession.builder().appName("test").master("local[*]").getOrCreate()
    import spark.implicits._
    val list = List((1, "A", 10), (1, "B", 20), (1, "C", 30), (2, "A", 20), (2, "B", 25), (2, "C", 30), (3, "A", 10),
      (3, "B", 20), (3, "C", 20))

val df = list.toDF("StudentId", "SubjectName", "Marks")
df.show() // source table as per above

val df1 = df.groupBy("StudentId").pivot("SubjectName", Seq("A", "B", "C")).agg(sum("Marks"))
df1.show()

val df2 = df1.withColumn("Total", col("A") + col("B") + col("C"))
df2.show // required destitnation

val df3 = df.groupBy("StudentId").agg(sum("Marks").as("Total"))
df3.show()

df1 is not displaying the sum/total column. it's displaying like below.
+---------+---+---+---+
|StudentId|  A|  B|  C|
+---------+---+---+---+
|        1| 10| 20| 30|
|        3| 10| 20| 20|
|        2| 20| 25| 30|
+---------+---+---+---+

df3 能够创建新的总计列,但为什么在 df1 中它不能创建新列?

拜托,任何人都可以帮助我解决我遗漏的问题或我对枢轴概念的理解有任何问题吗?

.agg 后接 pivot 仅适用于 pivoted 数据。要找到总和,您应该添加新列并按如下方式求和。

val cols = Seq("A", "B", "C")

val result = df.groupBy("StudentId")
  .pivot("SubjectName")
  .agg(sum("Marks"))
    .withColumn("Total", cols.map(col _).reduce(_ + _))

result.show(false)

输出:

+---------+---+---+---+-----+
|StudentId|A  |B  |C  |Total|
+---------+---+---+---+-----+
|1        |10 |20 |30 |60   |
|3        |10 |20 |20 |50   |
|2        |20 |25 |30 |75   |
+---------+---+---+---+-----+

这是 spark pivot 函数的预期行为,因为 .agg 函数应用于 pivoted columns这就是为什么您无法将标记总和视为新列的原因。

请参阅 this link 以获取有关数据透视表的官方文档。

示例:

scala> df.groupBy("StudentId").pivot("SubjectName").agg(sum("Marks") + 2).show()
+---------+---+---+---+
|StudentId|  A|  B|  C|
+---------+---+---+---+
|        1| 12| 22| 32|
|        3| 12| 22| 22|
|        2| 22| 27| 32|
+---------+---+---+---+

在上面的示例中,我们将 2 添加到所有旋转列。

示例 2:

使用 pivot 和 agg 获取计数

scala> df.groupBy("StudentId").pivot("SubjectName").agg(count("*")).show()
+---------+---+---+---+
|StudentId|  A|  B|  C|
+---------+---+---+---+
|        1|  1|  1|  1|
|        3|  1|  1|  1|
|        2|  1|  1|  1|
+---------+---+---+---+