SparkSQL: Wie gehe ich mit Nullwerten in einer benutzerdefinierten Funktion um?

Gegeben Tabelle 1 mit einer Spalte "x" vom Typ String. Ich möchte Tabelle 2 mit einer Spalte "y" erstellen, die eine ganzzahlige Darstellung der in "x" angegebenen Datumszeichenfolgen ist.

Wesentlic soll @ behaltnull Werte in Spalte "y".

Tabelle 1 (Datenrahmen df1):

+----------+
|         x|
+----------+
|2015-09-12|
|2015-09-13|
|      null|
|      null|
+----------+
root
 |-- x: string (nullable = true)

Tabelle 2 (Datenrahmen df2):

+----------+--------+                                                                  
|         x|       y|
+----------+--------+
|      null|    null|
|      null|    null|
|2015-09-12|20150912|
|2015-09-13|20150913|
+----------+--------+
root
 |-- x: string (nullable = true)
 |-- y: integer (nullable = true)

Während die benutzerdefinierte Funktion (udf) zum Konvertieren von Werten aus der Spalte "x" in die Werte der Spalte "y" wie folgt lautet:

val extractDateAsInt = udf[Int, String] (
  (d:String) => d.substring(0, 10)
      .filterNot( "-".toSet)
      .toInt )

und funktioniert, es ist nicht möglich, mit Nullwerten umzugehen.

Auch wenn ich so etwas tun kann wie

val extractDateAsIntWithNull = udf[Int, String] (
  (d:String) => 
    if (d != null) d.substring(0, 10).filterNot( "-".toSet).toInt 
    else 1 )

Ich habe keine Möglichkeit gefunden, @ "zu produzieren&quonull -Werte über udfs (natürlich alsInts kann nicht @ senull).

Meine aktuelle Lösung zur Erstellung von df2 (Tabelle 2) lautet wie folgt:

// holds data of table 1  
val df1 = ... 

// filter entries from df1, that are not null
val dfNotNulls = df1.filter(df1("x")
  .isNotNull)
  .withColumn("y", extractDateAsInt(df1("x")))
  .withColumnRenamed("x", "right_x")

// create df2 via a left join on df1 and dfNotNull having 
val df2 = df1.join( dfNotNulls, df1("x") === dfNotNulls("right_x"), "leftouter" ).drop("right_x")

Frage:

Die aktuelle Lösung scheint umständlich (und wahrscheinlich nicht effizient bezüglich Leistung). Gibt es einen besseren Weg?@ Spark-Entwickler: Gibt es einen TypNullableInt geplant / verfügbar, so dass folgendes udf möglich ist (siehe Code-Auszug)?

Code Auszug

val extractDateAsNullableInt = udf[NullableInt, String] (
  (d:String) => 
    if (d != null) d.substring(0, 10).filterNot( "-".toSet).toInt 
    else null )

Antworten auf die Frage(6)

Ihre Antwort auf die Frage