2017-01-24 2 views
2

дана dataframe:Спарк DataFrame - падение нулевых значений из столбца

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)| 
    +---+--------------------------+ 

Я хотел бы бросить null из колонки value. После удаления данные должны выглядеть так:

+---+--------------------------+ 
    |key|      value| 
    +---+--------------------------+ 
    |foo|ArrayBuffer(bar)   | 
    |bar|ArrayBuffer(one, two)  | 
    +---+--------------------------+ 

Любое предложение приветствуется. 10x

ответ

3

Здесь вам понадобится UDF. Например, с flatMap:

val filterOutNull = udf((xs: Seq[String]) => 
    Option(xs).map(_.flatMap(Option(_)))) 

df.withColumn("value", filterOutNull($"value")) 

, где внешний Option с map ручками 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)) 

и гарантирует, что мы не можем не с NPE при входе NULL/null по карте пинг

NULL -> null -> None -> None -> NULL 

где null является Scala null и NULL является SQL NULL.

Внутренняя flatMap сглаживает последовательность Options эффективно фильтрации nulls:

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) 
2

Вариант 1: с помощью ОДС:

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() 

Обратите внимание, что это менее эффективно ...

+0

Clear. Благодаря! – Toren

Смежные вопросы