了解pyspark中的惰性评估行为

时间:2019-11-25 18:08:36

标签: apache-spark pyspark apache-spark-sql

我有一个火花数据框,看起来像这样。

df.show()

| Id |
|----|
| 1  |
| 2  |
| 3  |

现在,我想添加一些分配有随机整数的列。我正在使用以下udf。 (我知道我们不需要为此使用udf)。这是我的代码。

random_udf = udf(lambda: random.randint(0, 1000), IntegerType())

df = df.withColumn("test_int", random_udf())
df.show()
| Id | test_int |
|----|----------|
| 1  | 51       |
| 2  | 111      |
| 3  | 552      |

现在,如果我添加另一列并显示它。 “ test_int”列中的值正在更改。

df = df.withColumn("test_int1", random_udf())
df.show()
| Id | test_int | test_int1 |
|----|----------|-----------|
| 1  | 429      | 429       |
| 2  | 307      | 307       |
| 3  | 69       | 69        |

我意识到,可能是spark在第二条显示语句上再次评估了数据框,并在代码中添加了persist语句。现在我的代码看起来像这样。

df = df.withColumn("test_int", random_udf()).persist()
df.rdd.count()  ## To kick off the evaluation
df.show()
| Id | test_int |
|----|----------|
| 1  | 459      |
| 2  | 552      |
| 3  | 89       |

df = df.withColumn("test_int1", random_udf())
df.show()
| Id | test_int | test_int1 |
|----|----------|-----------|
| 1  | 459      | 459       |
| 2  | 552      | 552       |
| 3  | 89       | 89        |

无论我做什么,两列似乎都具有相同的价值。我正在寻找这种行为的解释。我正在使用Azure databricks笔记本(Pyspark 2.4.4)。

1 个答案:

答案 0 :(得分:3)

这里有两点:

  1. 您需要了解计算机实际上并没有执行随机编号。这里发生的是为您的seed设置了random_udf()-一旦设置了该种子,“随机”将一次又一次重复,因为您要它执行相同的操作。在数据科学中,这非常重要,因为它可以确定性并允许您的实验可重复。有关更多信息,请参见numpy.random.seedhttps://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.random.seed.html)和random.seed

  2. 您实际上不应该将udf用于此类操作。为此,有一个非常好的(并行化的)pyspark.sql.functions.rand,它允许您设置seed。看到这里:https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.functions.rand