将字典传递给pyspark udf

时间:2018-10-29 19:56:55

标签: apache-spark pyspark user-defined-functions

我是pyspark的新手,我正在尝试使用udf映射一些字符串名称。我必须将一些数据值映射到新名称,因此我要从sparkdf发送列值,并将映射字段的字典发送到udf,而不是在{{1}之后写大量.when() }。

尝试仅将2个字符串传递给udf,并且可以,但是不传递字典。

.withColumn()

但是不存在关于方法col()的此错误。有什么想法吗?:

def stringToStr_function(checkCol, dict1) :
  for key, value in dict1.iteritems() :
    if(checkCol != None and checkCol==key): return value

stringToStr_udf = udf(stringToStr_function, StringType())

df = sparkdf.toDF().withColumn(
    "new_col",
     stringToStr_udf(
        lit("REQUEST"),
        {"REQUEST": "Requested", "CONFIRM": "Confirmed", "CANCEL": "Cancelled"}
     )
)

感谢您的帮助。我正在使用aws胶和Python 2.x,并且正在笔记本中进行测试。

2 个答案:

答案 0 :(得分:0)

linked duplicate所示:

  

最干净的解决方案是使用闭包传递其他参数

但是,对于此特定问题,您不需要udf。 (请参见Spark functions vs UDF performance?

您可以使用pyspark.sql.functions.when来实现IF-THEN-ELSE logic

from pyspark.sql.functions import coalesce, col, lit, when

def stringToStr_function(checkCol, dict1):
    return coalesce(
        *[when(col(checkCol) == key, lit(value)) for key, value in dict1.iteritems()]
    )

df = sparkdf.withColumn(
    "new_col",
    stringToStr_function(
        checkCol = lit("REQUEST"),
        dict1 = {"REQUEST": "Requested", "CONFIRM": "Confirmed", "CANCEL": "Cancelled"}
    )
)

如果when中的值与value相匹配,我们将遍历字典中的项目并使用checkCol返回key。将其包装到对pyspark.sql.functions.coalesce()的调用中,该调用将返回第一个非空值。

答案 1 :(得分:0)

以下是使用UDF和广播词典解决此问题的方法。 pault的解决方案很聪明,并且似乎依赖于字典的自动广播,因为它很小。不要认为pault的解决方案适用于大于自动广播限制的字典。在我看来,广播是编写PySpark代码的最安全方法。如果无法使用本机Spark函数来表达逻辑,则UDF方法也可能会更好。

假设您具有以下DataFrame。

+-------+
| status|
+-------+
|REQUEST|
|CONFIRM|
+-------+

这是将映射字典应用于列的代码。

def stringToStr(dict1_broadcasted):
    def f(x):
        return dict1_broadcasted.value.get(x)
    return F.udf(f)

df = spark.createDataFrame([["REQUEST",], ["CONFIRM",]]).toDF("status")
b = spark.sparkContext.broadcast({"REQUEST": "Requested", "CONFIRM": "Confirmed", "CANCEL": "Cancelled"})
df.withColumn(
    "new_col",
     stringToStr(b)(F.col("status"))
).show()
+-------+---------+
| status|  new_col|
+-------+---------+
|REQUEST|Requested|
|CONFIRM|Confirmed|
+-------+---------+

有关广播PySpark词典时可能遇到的所有错误的更多详细信息,请参见this post。很难做到正确,但却是工具包中拥有的强大技术。