我有一个用例,需要在字符串列上计算5000轮sha512。到目前为止,我尝试为此使用pyspark函数sha2,python“旧” UDF和python pandas udf。我正在寻找一种加快计算速度的方法。
对于pyspark ,我无法定义使用sha2 5000次的列(即使在显示列定义时也会出现堆栈溢出)-我使用循环定义了它:
for _ in range(5000):
column = sha2(column,512)
对于python ,我使用hashlib定义了类似的功能:
def sha(text):
for _ in range(5000):
text = hashlib.sha512(text.encode('utf-8')).hexdigest()
return text
但是它引入了序列化/反序列化和数据传输的开销。
我尝试为 pandas_udf 重写此功能,但是不幸的是,群集上的节点没有安装pyarrow,并且在需要运行原型之前它不会改变。
所以我正在寻找一种加快速度的方法。
编辑:我正在python 3.7中使用Spark 2.3。因此,我无权访问2.4中引入的高阶函数。
答案 0 :(得分:2)
确定只能使用SQL函数来完成此操作。拥有
df = spark.createDataFrame(["Hello World"], "string")
在 Spark 2.4 或更高版本(使用某些专有平台时更早)中,
df.selectExpr("""aggregate(
sequence(1, 5000), -- Dummy sequence
value, -- Init
(acc, x) -> sha2(acc, 512) -- Aggregation function
) AS hash""")
在 Spark 3.1 或更高版本中,您可以
from pyspark.sql.functions import aggregate, col, lit, sequence
df.select(aggregate(
sequence(lit(1), lit(5000)), # Dummy sequence
col("value"), # Init
lambda acc, _: sha2(acc, 512) # Aggregation function
).alias("hash"))
编辑(如果无法更新):
在实践中,经过5000轮哈希处理可以抵消数据移动带来的成本,因此您可以使用纯udf
来满足要求,尤其是对于原型制作。