计算一次UDF

Posted

技术标签:

【中文标题】计算一次UDF【英文标题】:Calculate UDF once 【发布时间】:2020-01-21 14:25:13 【问题描述】:

我想在 pyspark 数据框中有一个只计算一次的 UUID 列,以便我可以选择不同数据框中的列并使 UUID 相同。但是,当我选择该列时,会重新计算 UUID 列的 UDF。

这是我想要做的:

>>> uuid_udf = udf(lambda: str(uuid.uuid4()), StringType())
>>> a = spark.createDataFrame([[1, 2]], ['col1', 'col2'])
>>> a = a.withColumn('id', uuid_udf())
>>> a.collect()
[Row(col1=1, col2=2, id='5ac8f818-e2d8-4c50-bae2-0ced7d72ef4f')]
>>> b = a.select('id')
>>> b.collect()
[Row(id='12ec9913-21e1-47bd-9c59-6ddbe2365247')]  # Wanted this to be the same ID as above

可能的解决方法:rand()

一种可能的解决方法是使用 pyspark.sql.functions.rand() 作为我的随机源。但是,有两个问题:

1) 我想在 UUID 中包含字母,而不仅仅是数字,这样它就不需要那么长了

2) 虽然它在技术上有效,但它会产生丑陋的 UUID:

>>> from pyspark.sql.functions import rand, round
>>> a = a.withColumn('id', round(rand() * 10e16))
>>> a.collect()
[Row(col1=1, col2=2, id=7.34745165108606e+16)]

【问题讨论】:

【参考方案1】:

改用 Spark 内置的uuid 函数:

a = a.withColumn('id', expr("uuid()"))
b = a.select('id')

b.collect()
[Row(id='da301bea-4927-4b6b-a1cf-518dea8705c4')]

a.collect()
[Row(col1=1, col2=2, id='da301bea-4927-4b6b-a1cf-518dea8705c4')]

【讨论】:

我不知道这个。很高兴知道。适用于所有版本? 内置SQL函数uuid出现在2.3.0版本(see JIRA SPARK-20910)【参考方案2】:

您的 UUID 不断变化的原因是因为您的数据框在每次操作后都会一次又一次地计算。

为了稳定您的结果,您可以使用persistcache(取决于您的数据框的大小)。

df.persist()

df.show()                                                                                          
+---+--------------------+
| id|                uuid|
+---+--------------------+
|  0|e3db115b-6b6a-424...|
+---+--------------------+


b = df.select("uuid")                                                                              

b.show()                                                                                           
+--------------------+
|                uuid|
+--------------------+
|e3db115b-6b6a-424...|
+--------------------+

【讨论】:

很好的答案。我接受了另一个,因为它完全符合我的需要,但很高兴知道这一点。

以上是关于计算一次UDF的主要内容,如果未能解决你的问题,请参考以下文章

在 Pig 中只执行一次 UDF

再一次:存储过程与 TV-UDF [关闭]

Impala UDF的使用与一次报表异常

如何根据单元格颜色获取 UDF 以在 Excel 中自动更新

结构化流是如何执行 pandas_udf 的?

Spark迭代算法UDF在每次迭代中被多次触发