3

我在想如果有可能創建一個UDF接收兩個參數Column和另一個變量(Object,Dictionary或任何其他類型),然後做一些操作並返回結果。如何使用UDF將列與值進行比較?

其實,我試圖做到這一點,但我得到了一個例外。因此,我想知道是否有辦法避免這個問題。

df = sqlContext.createDataFrame([("Bonsanto", 20, 2000.00), 
           ("Hayek", 60, 3000.00), 
           ("Mises", 60, 1000.0)], 
           ["name", "age", "balance"]) 

comparatorUDF = udf(lambda c, n: c == n, BooleanType()) 

df.where(comparatorUDF(col("name"), "Bonsanto")).show() 

而且我得到以下錯誤:

AnalysisException: u"cannot resolve 'Bonsanto' given input columns name, age, balance;"

所以,很明顯的是,UDF「看到」 string「Bonsanto」作爲列名,實際上我想比較的紀錄值與第二個參數。

在另一方面,我知道這是可能使用一些運營商where子句中(但實際上我想知道,如果它是可以實現使用UDF),具體如下:

df.where(col("name") == "Bonsanto").show() 

#+--------+---+-------+ 
#| name|age|balance| 
#+--------+---+-------+ 
#|Bonsanto| 20| 2000.0| 
#+--------+---+-------+ 

回答

9

一切,傳遞給UDF被解釋爲列/列名稱。如果你想通過文字,你有兩個選擇:

  1. 傳遞參數,使用鑽營:

    def comparatorUDF(n): 
        return udf(lambda c: c == n, BooleanType()) 
    
    df.where(comparatorUDF("Bonsanto")(col("name"))) 
    

    這可以與任何類型的參數,只要它是序列化的使用。

  2. 使用SQL文本和當前實現:

    from pyspark.sql.functions import lit 
    
    df.where(comparatorUDF(col("name"), lit("Bonsanto"))) 
    

    這僅適用於支持的類型(字符串,數字,布爾值)。

相關問題