Scala Spark Dataframe:按特定列值对行进行分组和排序
当“ID”列编号从1开始到最大,然后从1重置时,我尝试对列进行排序 因此,前三行在“ID”上具有连续编号;因此,这些应按组秩=1分组。第四行和第五行在另一个组中,组秩=2 行按“rownum”列排序。我知道row_number窗口函数,但我不认为我可以应用这个用例,因为没有常量窗口。我只能考虑在数据帧中的每一行循环,但不确定当数字重置为1时如何更新列 val df=Seq( (1, 1 ), (2, 2 ), (3, 3 ), (4, 1), (5, 2), (6, 1), (7, 1), (8, 2) ).toDF(“rownum”、“ID”) df.show() 预期结果如下:Scala Spark Dataframe:按特定列值对行进行分组和排序,scala,apache-spark,apache-spark-sql,grouping,ranking,Scala,Apache Spark,Apache Spark Sql,Grouping,Ranking,当“ID”列编号从1开始到最大,然后从1重置时,我尝试对列进行排序 因此,前三行在“ID”上具有连续编号;因此,这些应按组秩=1分组。第四行和第五行在另一个组中,组秩=2 行按“rownum”列排序。我知道row_number窗口函数,但我不认为我可以应用这个用例,因为没有常量窗口。我只能考虑在数据帧中的每一行循环,但不确定当数字重置为1时如何更新列 val df=Seq( (1, 1 ), (2, 2 ), (3, 3 ), (4, 1), (5, 2), (6, 1), (7, 1), (8
您可以使用两个窗口函数完成此操作,第一个用于标记状态,第二个用于计算运行总和:
df
.withColumn("increase", $"ID" > lag($"ID",1).over(Window.orderBy($"rownum")))
.withColumn("group_rank_of_ID",sum(when($"increase",lit(0)).otherwise(lit(1))).over(Window.orderBy($"rownum")))
.drop($"increase")
.show()
给出:
+------+---+----------------+
|rownum| ID|group_rank_of_ID|
+------+---+----------------+
| 1| 1| 1|
| 2| 2| 1|
| 3| 3| 1|
| 4| 1| 2|
| 5| 2| 2|
| 6| 1| 3|
| 7| 1| 4|
| 8| 2| 4|
+------+---+----------------+
正如@Prithvi所指出的,我们可以在这里使用
lead
棘手的部分是为了使用窗口功能,如lead
,我们至少需要提供订单
考虑
val nextID=lag('ID,1,-1)超过Window.orderBy('rownum)
val isNewGroup='ID您知道超前-滞后函数吗?您可以使用它,为了匹配上一行,检查上一行是1,当前不是1,然后保持相同的排名,否则增加1。我使用了lead window函数,得到了下一行的“ID”值;我也理解你所说的逻辑,但不知道如何在Spark中实现。withColumn(“lead_col”,lead(col(“ID”),1)。over(Window.orderBy(col(“rownum”))给我一些时间,将帮助您完成一个工作。要使用Window
,您需要导入org.apache.spark.sql.expressions.Window
谢谢,这是个好主意。