2016-12-15 11 views
1

とオプションを使用するためにどのように私はこのようなデータセットを持っている:は、Spark UDF

+----+------+ 
|code|status| 
+-----------+ 
| 1| "new"| 
| 2| null| 
| 3| null| 
+----+------+ 

私は両方の列に依存してUDFを書きたいと思います。

df.withColumn("new_column", 
    when(pst_regs("status").isNull, 
    myFnUdf($"code", lit(false)) 
) 
    .otherwise(
    myFnUdf($"code", lit(true)) 
) 
) 

アプローチUDFにnullを処理するには:

は、私はそれがUDF外nullを処理し、2番目のパラメータとしてのブールを取るためにmyFnを書くことですthis answerにおける第二のアプローチ、次の作業です私が見たのはで引数を囲むことについて語っているthis answerです。私はこのようなコードを試してみました:

df.withColumn("new_column", myFnUdf($"code", $"status")) 

def myFn(code: Int, status: String) = (code, Option(status)) match { 
    case (1, "new") => "1_with_new_status" 
    case (2, Some(_)) => "2_with_any_status" 
    case (3, None) => "3_no_status" 
} 

をしかしnullの行がtype mismatch; found :None.type required Stringを与えます。私はまた、udfの作成中に成功せずにOptionで引数をラップしようとしました。 (オプションなし)この基本的な形は次のようになります。

myFnUdf = udf[String, Int, String](myFn(_:Int, _:String)) 

私はスカラ座に新たなんだので、私は、単純な何かが欠けてると確信しています。私の混乱の一部は、関数からudfsを作成するための異なる構文(例えば、https://jaceklaskowski.gitbooks.io/mastering-apache-spark/content/spark-sql-udfs.html)である可能性があるので、私は最良の方法を使用しているかどうかはわかりません。どんな助けにも感謝! @ user6910411あたり行方不明(1, "new")ケースと@sgvdコメントを追加するには、編集

EDIT

答えて

1

まず、使用しているコードがありますが、ここでは紛失しています。あなたの例であるmyFnを試して、val myFnUdf = udf(myFn _)というUDFを作り、それをdf.withColumn("new_column", myFnUdf($"code", $"status")).showで実行すると、タイプミスマッチは発生しませんが、代わりにMatchErrorとuser6910411と書いてあります。これは、(1, "new")に一致するパターンがないためです。

これ以外にも、通常nullの値ではなくScalaのオプションを使用するほうがよいでしょうが、この場合は必要ありません。次の例は、直接nullで動作します:

val my_udf = udf((code: Int, status: String) => status match { 
    case null => "no status" 
    case _ => "with status" 
}) 

df.withColumn("new_column", my_udf($"code", $"status")).show 

結果:

+----+------+-----------+ 
|code|status| new_column| 
+----+------+-----------+ 
| 1| new|with status| 
| 2| null| no status| 
| 2| null| no status| 
+----+------+-----------+ 

をオプション付きラッピングはまだかかわらず、動作しない:

val my_udf = udf((code: Int, status: String) => Option(status) match { 
    case None => "no status" 
    case Some(_) => "with status" 
}) 

これは、同じ結果を与えます。

+0

ありがとう@sgvd。私は両方の方法で作業しました(そして、欠落したケースを含めるように質問を更新しました)。あなたの助けに感謝。 –

関連する問題