【问题标题】:How do I get deterministic random ordering in pyspark?如何在 pyspark 中获得确定性随机排序?
【发布时间】:2019-04-04 06:21:33
【问题描述】:

我想随机排序一个数据帧,但以一种确定的方式。我认为这样做的方法是将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())

当我在本地机器上运行它时,它会打印出来

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

但在 EC2 实例上,它会打印

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

即使在不同的机器上运行,我如何才能获得确定性的随机排序?

我的 pyspark 版本是 2.4.1

编辑:顺便说一句,我应该补充一点,只是执行df.select(F.rand(seed=123)).show() 会在两台机器上产生相同的输出,所以这是orderByrand 组合的具体问题.

【问题讨论】:

  • 你的本地spark版本和EC2实例spark版本是多少?都一样吗?
  • 仅供参考,我得到的输出与您的 EC2 相同,我使用的是 pyspark 2.4.1
  • @JimTodd 是的,我的 spark 版本是一样的。
  • JVM版本呢?我得到的结果与 OpenJDK 1.8.0_191 不同
  • @JesseAmano 我的本地机器上有 java 版本 1.8.0_202。

标签: pyspark


【解决方案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|
+-----+-------------------+

【讨论】:

  • 感谢您的详细解答!我可以确认我在本地机器和 EC2 实例上都获得了相同的输出。此外,创建新列并不是绝对必要的;只需df.orderBy('value').orderBy(F.rand(seed=123)).show() 即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 2021-07-10
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多