Apache spark 为什么汇总后不显示总和&;支点

Apache spark 为什么汇总后不显示总和&;支点,apache-spark,apache-spark-sql,apache-spark-dataset,Apache Spark,Apache Spark Sql,Apache Spark Dataset,在这里,我有学生的分数,如下图所示,我想转置主题名称列,并希望在轴之后也得到总分数 源表,如: +---------+-----------+-----+ |StudentId|SubjectName|Marks| +---------+-----------+-----+ | 1| A| 10| | 1| B| 20| | 1| C| 30| | 2| A

在这里,我有学生的分数,如下图所示,我想转置主题名称列,并希望在轴之后也得到总分数

源表,如:

+---------+-----------+-----+
|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中它不能创建新列


请问,有谁能帮助我理解pivot概念时遗漏了什么或有什么错误吗?

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

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
函数应用于
数据透视列
,这就是您无法将标记总和视为新列的原因

有关pivot的官方文档,请参阅链接

示例:

在上面的示例中,我们向所有数据透视列添加了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|
+---------+---+---+---+

如果在这种情况下,我需要使用df2逻辑将总分作为一个单独的列来获取?@Ravi,是的,需要这样做才能将总分作为单独的列来获取@拉维,这个答案有用吗?如果是,请接受关闭线程的答案:)
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|
+---------+---+---+---+