火花数据框列上sha2的多次迭代

时间:2020-03-11 10:00:12

标签: apache-spark pyspark

我有一个用例,需要在字符串列上计算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,并且在需要运行原型之前它不会改变。

所以我正在寻找一种加快速度的方法。

  • 我不了解scala或java,但是我愿意尝试使用scala / java udf来加快速度-我是否认为在这种情况下切换到scala / java udf应该会加快速度是正确的吗?
  • pyspark是否缺少定义此类功能的方法?

编辑:我正在python 3.7中使用Spark 2.3。因此,我无权访问2.4中引入的高阶函数。

1 个答案:

答案 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来满足要求,尤其是对于原型制作。

相关问题