如何在 Spark/Scala 中查找具有许多空值的列

Posted

技术标签:

【中文标题】如何在 Spark/Scala 中查找具有许多空值的列【英文标题】:How to find columns with many nulls in Spark/Scala 【发布时间】:2017-08-04 22:36:59 【问题描述】:

我在 Spark/Scala 中有一个数据框,它有 100 列。许多其他列有许多空值。我想找到空值超过 90% 的列,然后将它们从我的数据框中删除。如何在 Spark/Scala 中做到这一点?

【问题讨论】:

【参考方案1】:

org.apache.spark.sql.functions.arrayudf 会有所帮助。

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

表演

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

排除以“a”开头的行。

【讨论】:

【参考方案2】:

假设你有一个这样的数据框:

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

使用agg函数计算NULL,并根据NULL计数和阈值过滤列,这里设置为1:

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

你会得到:

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

【讨论】:

以上是关于如何在 Spark/Scala 中查找具有许多空值的列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spark Scala 中的 Schema RDD [从案例类中创建] 中查找重复项以及相应的重复计数?

使用 Spark/Scala 有效地按键分组并查找在特定时间窗口中发生的事件的上一个时间戳

在表中为每个数据库查找具有空值的列[关闭]

Spark Scala:如何转换 DF 中的列

在 Hbase 中查找具有空值的行数

Spark Scala - 识别多行日期之间的差距