2017-08-04 1 views
1

Ich habe einen DataFrame wie folgt.Umgang mit Nullwerten in Dataframe

Value1 Value2 Value3 
30000 40000 50000 
null 20000 10000 

Auch ich habe ein UDF erstellt als

val testUDF=udf((a: Double, b: Double, c: Double) => { 
    if(a==null && b!=null && c!=null) 
     b+c 
    else 
     a+b+c 
}) 

I wie unten einen Code haben.

input.withColumn("checkNull", testUDF(col("value1"),col("value2"),col("value3"))).show 

Resultierende Datenrahmen ist als

Value1 Value2 Value3 checkNull 
30000 40000 50000 120000 
null 20000 10000 null 

hier anstelle von 3000 für die zweite Zeile für die Spalte "checkNUll" anzeigt, ist es angezeigt, null. Was mache ich falsch in meinem Code? Ich möchte es nicht mit 0 ersetzen. Weil, wenn ich Multiplikation anstelle von oben tun will, wird es fehlschlagen.

+0

haben Sie versucht "ist null" und "ist nicht null" statt? – Wonjin

+1

Nullen durch 0 ersetzen und dann hinzufügen. – philantrovert

+0

Ja. a.isNull löst einen Fehler aus, der besagt, dass isNull kein Mitglied von Double ist. – KishoreKumar

Antwort

2

Es gibt so viele Möglichkeiten, zu tun, was Sie versuchen, die aktuellen Informationen zu tun und mit, würde ich vorschlagen coalesce mit:

df.withColumn("x4", 
        coalesce(
         $"x1".cast("long") * $"x2" * $"x3", 
         $"x2".cast("long") * $"x3", 
         lit(0) 
        ) 
).show 
+-----+-----+-----+--------------+ 
| x1| x2| x3|   x4| 
+-----+-----+-----+--------------+ 
|30000|40000|50000|60000000000000| 
| null|20000|10000|  200000000| 
+-----+-----+-----+--------------+ 

Ich bin wegen dieser Frage long Gießen Why do these two multiplication operations give different results?

Hier füllt eine andere Lösung die Säule x1 mit 1 zu multiplizieren:

df.na.fill(1, Seq("x1")).withColumn("x4", $"x1".cast("long") * $"x2" * $"x3").show 

Es ergeben sich die s ame Ergebnisse.

EDIT: Hier ist eine dritte Möglichkeit, das zu tun:

df.withColumn("x4", 
       when($"x1".isNull and $"x2".isNotNull and $"x3".isNotNull, $"x2".cast("long") * $"x3") 
       .otherwise($"x1".cast("long") * $"x2"* $"x3") 
).show 

EDIT 2: Hier einige Ressourcen über Dealing with Null in Apache Spark zu lesen.

+0

Wie würde der erste Teil zu '200000000' führen? Ein "Null" zu "Lang" zu werfen, macht nichts, oder? Würden Sie nicht eine "0" in der zweiten Zeile bekommen, weil die ersten zwei Parameter zum "Zusammenfassen" zu einem "Null" führen würden? – philantrovert

+0

Wenn Sie einen Nullwert in long eingeben, erhalten Sie eine Null. Der erste Ausdruck ist also null. Ich bin mir dabei sicher. – eliasah

+1

Oh, ich dachte, es wäre '$" x1 "' auch im zweiten Parameter. Mein Fehler. – philantrovert

0

Sie müssen Filter in solch einer Bedingung verwenden, denn wenn Wert1 null ist, wird es nicht udf aufrufen.

val testStr = """[{"Val1":1000, "Val2":2000, "Val3":4000},{"Val2":2000, "Val3":4000}]""" 
    val rdd = sc.parallelize(Seq(testStr)) 
      val df = sqlContext.read.json(rdd) 

      val newdf = df.filter(df.col("Val1").isNotNull).withColumn("checkNull",df.col("Val1")+df.col("Val2")+df.col("Val3")) 
      val newdfw2 = df.filter(df.col("Val1").isNull).withColumn("checkNull",df.col("Val2")+df.col("Val3")) 
      val alldf = newdf.unionAll(newdfw2) 
      alldf.show() 
0

Sie einfach na.fill(0.0) können alle null Werte als 0.0 und nur + Notation ersetzen die Spaltenwerte als

df.select($"Value1".cast(DoubleType), $"Value2".cast(DoubleType), $"Value3".cast(DoubleType)) 
    .na.fill(0.0) 
    .withColumn("checkNull", $"Value1"+$"Value2"+$"Value3") 
    .show(false) 

Gegeben Datenrahmen als

+------+------+------+ 
|Value1|Value2|Value3| 
+------+------+------+ 
|30000 |40000 |50000 | 
|null |20000 |10000 | 
+------+------+------+ 

Sie sollten hinzufügen Ausgabe als

+-------+-------+-------+---------+ 
|Value1 |Value2 |Value3 |checkNull| 
+-------+-------+-------+---------+ 
|30000.0|40000.0|50000.0|120000.0 | 
|0.0 |20000.0|10000.0|30000.0 | 
+-------+-------+-------+---------+ 

Ich hoffe, die Antwort ist hilfreich

+0

Es gibt keine Möglichkeit, meine UDF zu modifizieren ist es? – KishoreKumar

+0

Ich denke, du willst keine besseren Lösungen, oder? :) –

Verwandte Themen