Scala 如何为Spark中另一列中的每个唯一值找到一列的最大值?
假设我有一个类似的数据集:Scala 如何为Spark中另一列中的每个唯一值找到一列的最大值?,scala,apache-spark,pyspark,apache-spark-sql,Scala,Apache Spark,Pyspark,Apache Spark Sql,假设我有一个类似的数据集: 我的最终产品需要在一周中的每一天与当天活动最多的地方排成一行。i、 e.Mon Place A 56、Wed Place C 64等。我尝试过使用窗口函数,正在使用max和groupie,但我感到困惑。出于您的目的,您需要编写窗口函数: val df = Seq( ("Mon", "Place A", 10), ("Mon", "Place B", 42), ("W
我的最终产品需要在一周中的每一天与当天活动最多的地方排成一行。i、 e.Mon Place A 56、Wed Place C 64等。我尝试过使用窗口函数,正在使用max和groupie,但我感到困惑。出于您的目的,您需要编写
窗口函数
:
val df = Seq(
("Mon", "Place A", 10),
("Mon", "Place B", 42),
("Wed", "Place C", 41),
("Thurs", "Place D", 45),
("Fri", "Place E", 64),
("Fri", "Place A", 12),
("Wed", "Place F", 54),
("Wed", "Place A", 1)
).toDF("day", "place", "number")
df.show()
df.withColumn("orderedNumberForDay",
row_number()
.over(
Window.orderBy(col("number").desc)
.partitionBy("day")
)
).filter(col("orderedNumberForDay") === lit(1))
.select("day", "place", "number")
.show()
/*
+-----+-------+------+ +-----+-------+------+
| day| place|number| | day| place|number|
+-----+-------+------+ +-----+-------+------+
| Mon|Place A| 10| | Mon|Place B| 42|
| Mon|Place B| 42| ===>> | Wed|Place F| 54|
| Wed|Place C| 41| | Fri|Place E| 64|
|Thurs|Place D| 45| |Thurs|Place D| 45|
| Fri|Place E| 64| +-----+-------+------+
| Fri|Place A| 12|
| Wed|Place F| 54|
| Wed|Place A| 1|
+-----+-------+------+
*/
只需简单解释一下它的工作原理
首先需要添加带有窗口功能的列
结果,如下所示:
df.withColumn("orderedNumberForDay",
row_number()
.over(
Window.orderBy(col("number").desc)
.partitionBy("day")
)
)
row\u number()
-是分区内的行计数器<代码>分区
类似于分组依据
中的分组partitionBy(“day”)
仅使用相同的day
列值对窗口进行分组。最后,我们必须按desc
顺序中的number
对该窗口进行排序,因此有orderBy(col(“number”).desc
在我们的窗口函数中
就像是从窗口
到窗口
中一些有用的计算的桥梁,它只是绑定行数
和窗口函数
执行此阶段后,我们将获得以下数据:
+-----+-------+------+-------------------+
| day| place|number|orderedNumberForDay|
+-----+-------+------+-------------------+
| Mon|Place B| 42| 1|
| Mon|Place A| 10| 2|
| Wed|Place F| 54| 1|
| Wed|Place C| 41| 2|
| Wed|Place A| 1| 3|
| Fri|Place E| 64| 1|
| Fri|Place A| 12| 2|
|Thurs|Place D| 45| 1|
+-----+-------+------+-------------------+
因此,我们所需要的就是过滤行,其中orderedNumberForDay
等于1
-它将使用max
number
并选择开始的列:日期、地点、编号
。最终结果将是:
+-----+-------+------+
| day| place|number|
+-----+-------+------+
| Mon|Place B| 42|
| Wed|Place F| 54|
| Fri|Place E| 64|
|Thurs|Place D| 45|
+-----+-------+------+
Spark 3.0引入了聚合功能,它完全满足您的需求:
df.groupBy(“日”)
.agg(expr(“max_by(place,number)”),max(“number))
.show()
结果:
+-----+---------------------+-----------+
|day | max|u by(地点、编号)| max(编号)|
+-----+---------------------+-----------+
|周一B街42号|
|星期三广场F 54|
|星期五E广场64号|
|星期四D街45号|
+-----+---------------------+-----------+