计算一次UDF
Calculate UDF once
我想在 pyspark 数据框中有一个只计算一次的 UUID 列,这样我就可以 select 不同数据框中的列并使 UUID 相同。但是,当我 select 列时,会重新计算 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)]
您的 UUID 不断变化的原因是因为您的数据帧在每次操作后都会被反复计算。
为了稳定你的结果,你可以只使用 persist
或 cache
(取决于你的数据帧的大小)。
df.persist()
df.show()
+---+--------------------+
| id| uuid|
+---+--------------------+
| 0|e3db115b-6b6a-424...|
+---+--------------------+
b = df.select("uuid")
b.show()
+--------------------+
| uuid|
+--------------------+
|e3db115b-6b6a-424...|
+--------------------+
改为使用 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')]
我想在 pyspark 数据框中有一个只计算一次的 UUID 列,这样我就可以 select 不同数据框中的列并使 UUID 相同。但是,当我 select 列时,会重新计算 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)]
您的 UUID 不断变化的原因是因为您的数据帧在每次操作后都会被反复计算。
为了稳定你的结果,你可以只使用 persist
或 cache
(取决于你的数据帧的大小)。
df.persist()
df.show()
+---+--------------------+
| id| uuid|
+---+--------------------+
| 0|e3db115b-6b6a-424...|
+---+--------------------+
b = df.select("uuid")
b.show()
+--------------------+
| uuid|
+--------------------+
|e3db115b-6b6a-424...|
+--------------------+
改为使用 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')]