我有一个看起来像
的数据框+--------+---+------+----+
|group_id| id| text|type|
+--------+---+------+----+
| 1| 1| one| a|
| 1| 1| two| t|
| 1| 2| three| a|
| 1| 2| four| t|
| 1| 5| five| a|
| 1| 6| six| t|
| 1| 7| seven| a|
| 1| 9| eight| t|
| 1| 9| nine| a|
| 1| 10| ten| t|
| 1| 11|eleven| a|
+--------+---+------+----+
如果我通过在group_id上对它进行分区并按id对其进行排序来执行Window操作,那么orderby将确保已经排序(排序)的行保持相同的顺序?
例如
window_spec = Window.partitionBy(df.group_id).orderBy(df.id)
df = df.withColumn("row_number", row_number().over(window_spec))
将永远是
+--------+---+------+----+------+
|group_id| id| text|type|row_number|
+--------+---+------+----+------+
| 1| 1| one| a| 1|
| 1| 1| two| t| 2|
| 1| 2| three| a| 3|
| 1| 2| four| t| 4|
| 1| 5| five| a| 5|
| 1| 6| six| t| 6|
| 1| 7| seven| a| 7|
| 1| 9| eight| t| 8|
| 1| 9| nine| a| 9|
| 1| 10| ten| t| 10|
| 1| 11|eleven| a| 11|
+--------+---+------+----+------+
简而言之,我的问题是,Spark Window的orderBy如何处理已经排序(排序)的行?我的假设是稳定的,即它不会更改已排序行的顺序,但是我在文档中找不到与此相关的任何内容。如何确定我的假设是正确的?
谢谢。
答案 0 :(得分:0)
首先,为那些可能不知道稳定排序定义的读者设置上下文,我将引用此StackOverflow answer by Joey Adams
“如果两个对象相等,则说排序算法是稳定的 键在排序输出中的显示顺序与它们在 输入数组进行排序”-Joey Adams
现在,可以将spark中的窗口函数视为对整个集合的mini-DataFrame进行Spark处理,其中每个mini-DataFrame是在指定键(在这种情况下为“ group_id”)上创建的。
也就是说,如果提供的数据帧的“ group_id” = 2,我们将最终得到两个Windows,其中第一个仅包含“ group_id” = 1的数据,另一个仅包含“ group_id” = 2的数据。
注意这一点很重要,因为我们可以在示例数据帧上测试.orderBy()调用的效果,而不必真正担心Window会发生什么。要强调正在发生的事情:
因此,对于预排序的输入,例如:
df = spark.createDataFrame(
[
{'group_id': 1, 'id': 1, 'text': 'one', 'type': 'a'},
{'group_id': 1, 'id': 1, 'text': 'two', 'type': 't'},
{'group_id': 1, 'id': 2, 'text': 'three', 'type': 'a'},
{'group_id': 1, 'id': 2, 'text': 'four', 'type': 't'},
{'group_id': 1, 'id': 5, 'text': 'five', 'type': 'a'},
{'group_id': 1, 'id': 6, 'text': 'six', 'type': 't'},
{'group_id': 1, 'id': 7, 'text': 'seven', 'type': 'a'},
{'group_id': 1, 'id': 9, 'text': 'eight', 'type': 't'},
{'group_id': 1, 'id': 9, 'text': 'nine', 'type': 'a'},
{'group_id': 1, 'id': 10, 'text': 'ten', 'type': 't'},
{'group_id': 1, 'id': 11, 'text': 'eleven', 'type': 'a'}
]
)
+--------+---+------+----+
|group_id| id| text|type|
+--------+---+------+----+
| 1| 1| one| a|
| 1| 1| two| t|
| 1| 2| three| a|
| 1| 2| four| t|
| 1| 5| five| a|
| 1| 6| six| t|
| 1| 7| seven| a|
| 1| 9| eight| t|
| 1| 9| nine| a|
| 1| 10| ten| t|
| 1| 11|eleven| a|
+--------+---+------+----+
我们申请:
df.orderBy('id').show()
结果:
+--------+---+------+----+
|group_id| id| text|type|
+--------+---+------+----+
| 1| 1| one| a|
| 1| 1| two| t|
| 1| 2| three| a|
| 1| 2| four| t|
| 1| 5| five| a|
| 1| 6| six| t|
| 1| 7| seven| a|
| 1| 9| nine| a|
| 1| 9| eight| t|
| 1| 10| ten| t|
| 1| 11|eleven| a|
+--------+---+------+----+
乍一看,这似乎很稳定,但让我们将其应用于具有text =“ two”的行和text =“ three”的行的DataFrame:
df = spark.createDataFrame(
[
{'group_id': 1, 'id': 1, 'text': 'one', 'type': 'a'},
{'group_id': 1, 'id': 2, 'text': 'three', 'type': 'a'},
{'group_id': 1, 'id': 1, 'text': 'two', 'type': 't'},
{'group_id': 1, 'id': 2, 'text': 'four', 'type': 't'},
{'group_id': 1, 'id': 5, 'text': 'five', 'type': 'a'},
{'group_id': 1, 'id': 6, 'text': 'six', 'type': 't'},
{'group_id': 1, 'id': 7, 'text': 'seven', 'type': 'a'},
{'group_id': 1, 'id': 9, 'text': 'eight', 'type': 't'},
{'group_id': 1, 'id': 9, 'text': 'nine', 'type': 'a'},
{'group_id': 1, 'id': 10, 'text': 'ten', 'type': 't'},
{'group_id': 1, 'id': 11, 'text': 'eleven', 'type': 'a'}
]
)
+--------+---+------+----+
|group_id| id| text|type|
+--------+---+------+----+
| 1| 1| one| a|
| 1| 2| three| a|
| 1| 1| two| t|
| 1| 2| four| t|
| 1| 5| five| a|
| 1| 6| six| t|
| 1| 7| seven| a|
| 1| 9| eight| t|
| 1| 9| nine| a|
| 1| 10| ten| t|
| 1| 11|eleven| a|
+--------+---+------+----+
然后申请:
df.orderBy(df.id).show()
这将导致:
+--------+---+------+----+
|group_id| id| text|type|
+--------+---+------+----+
| 1| 1| two| t|
| 1| 1| one| a|
| 1| 2| four| t|
| 1| 2| three| a|
| 1| 5| five| a|
| 1| 6| six| t|
| 1| 7| seven| a|
| 1| 9| nine| a|
| 1| 9| eight| t|
| 1| 10| ten| t|
| 1| 11|eleven| a|
+--------+---+------+----+
您可以看到,即使text =“ one”和text =“ two”行以相同的顺序出现,.orderBy()也会将它们交换。因此,我们可以假设.orderBy()不是稳定的排序。