Apache spark 在Spark Dataframe中的窗口上创建组id
我有一个数据框,我想在每个窗口分区中给出id。比如我有Apache spark 在Spark Dataframe中的窗口上创建组id,apache-spark,pyspark,apache-spark-sql,window-functions,Apache Spark,Pyspark,Apache Spark Sql,Window Functions,我有一个数据框,我想在每个窗口分区中给出id。比如我有 id | col | 1 | a | 2 | a | 3 | b | 4 | c | 5 | c | 所以我想要(基于列col分组) 我想使用一个窗口函数,但无论如何我都找不到为每个窗口分配Id的方法。我需要像这样的东西: w = Window().partitionBy('col') df = df.withColumn("group", id().over(w)) 有没有办法做到那样的事。(我不能简单
id | col |
1 | a |
2 | a |
3 | b |
4 | c |
5 | c |
所以我想要(基于列col分组)
我想使用一个窗口函数,但无论如何我都找不到为每个窗口分配Id的方法。我需要像这样的东西:
w = Window().partitionBy('col')
df = df.withColumn("group", id().over(w))
有没有办法做到那样的事。(我不能简单地使用col作为组id,因为我想在多个列上创建一个窗口)您可以为distinct
col
分配一个行号,并将其与原始数据帧相连接
val data = Seq(
(1, "a"),
(2, "a"),
(3, "b"),
(4, "c"),
(5, "c")
).toDF("id","col")
val df2 = data.select("col").distinct()
.withColumn("group", row_number().over(Window.orderBy("col")))
val result = data.join(df2, Seq("col"), "left")
.drop("col")
代码位于scala
中,但可以轻松更改为pyspark
希望这对您有所帮助您可以为distinctcol
和self指定一个行号
,并将其与原始数据帧连接起来
val data = Seq(
(1, "a"),
(2, "a"),
(3, "b"),
(4, "c"),
(5, "c")
).toDF("id","col")
val df2 = data.select("col").distinct()
.withColumn("group", row_number().over(Window.orderBy("col")))
val result = data.join(df2, Seq("col"), "left")
.drop("col")
代码位于scala
中,但可以轻松更改为pyspark
希望这有助于简单地使用densite\u-rank
内置函数over-Window函数应该可以得到您想要的结果
from pyspark.sql import window as W
import pyspark.sql.functions as f
df.select('id', f.dense_rank().over(W.Window.orderBy('col')).alias('group')).show(truncate=False)
应该给你什么
+---+-----+
|id |group|
+---+-----+
|1 |1 |
|2 |1 |
|3 |2 |
|4 |3 |
|5 |3 |
+---+-----+
只需在窗口函数上使用densite\u-rank
内置函数,即可获得所需的结果
from pyspark.sql import window as W
import pyspark.sql.functions as f
df.select('id', f.dense_rank().over(W.Window.orderBy('col')).alias('group')).show(truncate=False)
应该给你什么
+---+-----+
|id |group|
+---+-----+
|1 |1 |
|2 |1 |
|3 |2 |
|4 |3 |
|5 |3 |
+---+-----+
我认为这适用于我的案例,我会很快测试它,如果它适合我的问题,我会很快测试它,如果它适合我的问题,我会很快关闭问题,谢谢你,这是我所需要的。这项工作,但不能在大数据上扩展。这样做一个全局排名将导致spark将所有数据重新排列到一个执行者来执行排名。谢谢,这是我所需要的。这项工作不适用于大数据。这样做一个全局排名将导致spark将所有数据洗牌到一个执行器来执行排名。