2017-08-04 1 views
0

Ich habe ein Datenframe in Spark/Scala, die 100 von Spalte hat. Viele der anderen Spalten haben viele Nullwerte. Ich würde gerne die Spalten mit mehr als 90% Nullen finden und sie dann aus meinem Datenrahmen löschen. Wie kann ich das in Spark/Scala machen?So finden Sie Spalten mit vielen Nullen in Spark/Scala

Antwort

2

org.apache.spark.sql.functions.array und udf Willen Hilfe.

import spark.implicits._ 
import org.apache.spark.sql.functions._ 

val df = sc.parallelize[(String, String, String, String, String, String, String, String, String, String)](
    Seq(
    ("a", null, null, null, null, null, null, null, null, null), // 90% 
    ("b", null, null, null, null, null, null, null, null, ""), // 80% 
    ("c", null, null, null, null, null, null, null, "", "") // 70% 
) 
).toDF("c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9","c10") 

// count nulls then check the condition 
val check_90_null = udf { xs: Seq[String] => 
    xs.count(_ == null) >= (xs.length * 0.9) 
} 

// all columns as array 
val columns = array(df.columns.map(col): _*) 

// filter out 
df.where(not(check_90_null(columns))) 
    .show() 

zeigt

+---+----+----+----+----+----+----+----+----+---+ 
| c1| c2| c3| c4| c5| c6| c7| c8| c9|c10| 
+---+----+----+----+----+----+----+----+----+---+ 
| b|null|null|null|null|null|null|null|null| | 
| b|null|null|null|null|null|null|null| | | 
+---+----+----+----+----+----+----+----+----+---+ 

die der Reihe gestartet "a" wird ausgeschlossen.

2

Angenommen, Sie einen Datenrahmen wie dieses:

val df = Seq((Some(1.0), Some(2), Some("a")), 
      (null, Some(3), null), 
      (Some(2.0), Some(4), Some("b")), 
      (null, null, Some("c")) 
      ).toDF("A", "B", "C") 

df.show 
+----+----+----+ 
| A| B| C| 
+----+----+----+ 
| 1.0| 2| a| 
|null| 3|null| 
| 2.0| 4| b|  
|null|null| c| 
+----+----+----+ 

Count NULL agg Funktion und Filter Spalten basierend auf den Null-Zählungen und Schwellen, setzen sie 1, hier zu sein mit:

val null_thresh = 1     // if you want to use percentage 
            // val null_thresh = df.count() * 0.9 

val to_keep = df.columns.filter(
    c => df.agg(
     sum(when(df(c).isNull, 1).otherwise(0)).alias(c) 
    ).first().getLong(0) <= null_thresh 
) 

df.select(to_keep.head, to_keep.tail: _*).show 

und Sie erhalten:

+----+----+ 
| B| C| 
+----+----+ 
| 2| a| 
| 3|null| 
| 4| b| 
|null| c| 
+----+----+ 
Verwandte Themen