繁体   English   中英

将没有返回值的 Python Lambda 函数转换为 Pyspark

[英]Transforming Python Lambda function without return value to Pyspark

我在 Python 中有一个有效的 lambda 函数,用于计算 dataset1 中的每个字符串与 dataset2 中的字符串之间的最高相似度。 在迭代过程中,它将字符串、最佳匹配和相似性以及其他一些信息写入 bigquery。 没有返回值,因为该函数的目的是在 bigquery 数据集中插入一行。 这个过程需要相当长的时间,这就是为什么我想使用 Pyspark 和 Dataproc 来加速这个过程。

将 Pandas 数据帧转换为 spark 很容易。 我在注册我的 udf 时遇到了麻烦,因为它没有返回值,而 pyspark 需要一个。 此外,我不明白如何将 python 中的“应用”函数映射到 pyspark 变体。 所以基本上我的问题是如何转换下面的 python 代码以在 spark 数据帧上工作。

以下代码适用于常规 Python 环境:

def embargomatch(name, code, embargo_names):
     find best match 
     insert best match and additional information to bigquery

customer_names.apply(lambda x: embargoMatch(x['name'], x['customer_code'],embargo_names),axis=1)

因为 pyspark 需要返回类型,所以我在 udf 中添加了“return 1”并尝试了以下操作:


customer_names = spark.createDataFrame(customer_names)

from pyspark.sql.types import IntegerType
embargo_match_udf = udf(lambda x: embargoMatch(x['name'], x['customer_code'],embargo_names), IntegerType())

现在我一直在尝试应用 select 函数,因为我不知道要提供什么参数。

我怀疑您对如何将多列传递给 udf 感到困惑——这是该问题的一个很好的答案: Pyspark: Pass multiple columns in UDF

与其基于包装函数的 lambda 创建embargomatch考虑通过直接基于embargomatch创建embargomatch简化。

embargo_names = ...

# The parameters here are the columns passed into the udf
def embargomatch(name, customer_code):
    pass
embargo_match_udf = udf(embargomatch, IntegerType())
customer_names.select(embargo_match_udf(array('name', 'customer_code')).alias('column_name'))

话虽如此,但怀疑您的 udf 没有返回任何内容——我通常将 udfs 视为向数据帧添加列的一种方式,但不会产生副作用。 如果要将记录插入 bigquery,请考虑执行以下操作:

customer_names.select('column_name').write.parquet('gs://some/path')
os.system("bq load --source_format=PARQUET [DATASET].[TABLE] gs://some/path")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM