如何在pyspark中获得确定性随机排序?

时间:2019-04-02 07:06:43

标签: pyspark

我想以确定性的方式随机排序数据框。我认为实现此目的的方法是将pyCUDA与种子函数orderBy一起使用。但是,我发现这在不同的机器上是不确定的。例如,考虑以下代码:

rand

当我在本地计算机上运行它时,它会打印

from pyspark.sql import types as T, functions as F
df = spark.createDataFrame(range(10), T.IntegerType())
df = df.orderBy(F.rand(seed=123))
print(df.show())

但是在EC2实例上,它会打印

+-----+
|value|
+-----+
|    3|
|    4|
|    9|
|    7|
|    8|
|    0|
|    5|
|    6|
|    2|
|    1|
+-----+

即使在不同的计算机上运行,​​如何获得确定性的随机排序?

我的pyspark版本是2.4.1

编辑:顺便说一句,我应该补充一点,就是+-----+ |value| +-----+ | 9| | 5| | 6| | 7| | 0| | 1| | 4| | 8| | 3| | 2| +-----+ 会在两台计算机上产生相同的输出,因此,df.select(F.rand(seed=123)).show()的组合尤其存在问题和orderBy

1 个答案:

答案 0 :(得分:1)

感谢您提供的其他编辑信息!事实证明这是一个非常重要的线索。

问题

认为这里的问题是,您将一个伪随机生成的列附加到一个已经随机排列的数据集上,并且现有的随机性不是确定性的,因此附加另一个随机性来源确定性没有帮助。

您可以通过改写orderBy呼叫来验证这一点,例如:

df.withColumn('order', F.rand(seed=123)).orderBy(F.col('order').asc())

如果我是对的,您会在两台计算机上看到相同的随机值,但是它们将附加到不同的行:随机值附加到行的顺序是随机的!

解决方案

如果是真的,解决方案应该非常简单:在顶部应用随机(但仍是确定性)顺序之前,对“真实”值应用确定性,非随机排序。

df.orderBy(F.col('value').asc()).withColumn('order', F.rand(seed=123)).orderBy(F.col('order').asc())

应该在两台机器上产生相似的输出。 我的结果:

+-----+-------------------+
|value|              order|
+-----+-------------------+
|    4|0.13617504799810343|
|    5|0.13778573503201175|
|    6|0.15367835411103337|
|    9|0.43774287147238644|
|    0| 0.5029534413816527|
|    1| 0.5230701153994686|
|    7|  0.572063607751534|
|    8| 0.7689696831405166|
|    3|   0.82540915099773|
|    2| 0.8535692890157796|
+-----+-------------------+