Как получить детерминированный случайный порядок в pyspark? - PullRequest
1 голос
/ 02 апреля 2019

Я бы хотел случайным образом упорядочить данные, но детерминированным способом.Я думал, что способ сделать это - использовать 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() производит одинаковый вывод на обеих машинах, так что это определенно проблема с комбинацией orderBy и rand.

1 Ответ

1 голос
/ 04 апреля 2019

Спасибо за дополнительную информацию от вашего редактирования!Это оказалось довольно важной подсказкой.

Проблема

Я думаю проблема здесь в том, что вы присоединяете псевдослучайно сгенерированный столбец к уже случайно выбранномуупорядоченный набор данных, и существующая случайность не является детерминированной, поэтому присоединение другого источника случайности, который является детерминированным, не помогает.

Вы можете проверить это, перефразировав свой вызов orderBy как:

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

Если я прав, вы увидите одинаковые случайные значения на обеих машинах, но они будут прикреплены к разным строкам: порядок, в котором случайные значения прикрепляются к строкам, является случайным!

Решение

И если это правда, решение должно быть довольно простым: применить детерминистическое неслучайное упорядочение над «реальными» значениями, прежде чем применять случайный (но все еще детерминированный) порядок дляtop.

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|
+-----+-------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...