[英]Spark DataFrame - drop null values from column
給定一個數據框:
val df = sc.parallelize(Seq(("foo", ArrayBuffer(null,"bar",null)), ("bar", ArrayBuffer("one","two",null)))).toDF("key", "value")
df.show
+---+--------------------------+
|key| value|
+---+--------------------------+
|foo|ArrayBuffer(null,bar,null)|
|bar|ArrayBuffer(one, two,null)|
+---+--------------------------+
我想從列value
刪除null
。 刪除后,數據框應如下所示:
+---+--------------------------+
|key| value|
+---+--------------------------+
|foo|ArrayBuffer(bar) |
|bar|ArrayBuffer(one, two) |
+---+--------------------------+
歡迎任何建議。 10倍
這里你需要一個UDF。 例如使用flatMap
:
val filterOutNull = udf((xs: Seq[String]) =>
Option(xs).map(_.flatMap(Option(_))))
df.withColumn("value", filterOutNull($"value"))
其中帶有map
外部Option
處理NULL
列:
Option(null: Seq[String]).map(identity)
Option[Seq[String]] = None
Option(Seq("foo", null, "bar")).map(identity)
Option[Seq[String]] = Some(List(foo, null, bar))
並通過映射確保當輸入為NULL
/ null
時我們不會因 NPE 失敗
NULL -> null -> None -> None -> NULL
其中null
是 Scala null
, NULL
是 SQL NULL
。
內部flatMap
平了一系列有效過濾nulls
的Options
:
Seq("foo", null, "bar").flatMap(Option(_))
Seq[String] = List(foo, bar)
一個更命令式的等價物可能是這樣的:
val imperativeFilterOutNull = udf((xs: Seq[String]) =>
if (xs == null) xs
else for {
x <- xs
if x != null
} yield x)
選項 1:使用 UDF:
val filterNull = udf((arr : Seq[String]) => arr.filter((x: String) => x != null))
df.withColumn("value", filterNull($"value")).show()
選項 2:無 UDF
df.withColumn("value", explode($"value")).filter($"value".isNotNull).groupBy("key").agg(collect_list($"value")).show()
請注意,這效率較低......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.