Spark 仅获取具有一个或多个空值的列
Posted
技术标签:
【中文标题】Spark 仅获取具有一个或多个空值的列【英文标题】:Spark Get only columns that have one or more null values 【发布时间】:2018-01-15 11:07:16 【问题描述】:我想从数据框中获取至少包含一个空值的列的名称。
考虑下面的数据框:
val dataset = sparkSession.createDataFrame(Seq(
(7, null, 18, 1.0),
(8, "CA", null, 0.0),
(9, "NZ", 15, 0.0)
)).toDF("id", "country", "hour", "clicked")
我想获取列名“国家”和“小时”。
id country hour clicked
7 null 18 1
8 "CA" null 0
9 "NZ" 15 0
【问题讨论】:
【参考方案1】:这是一种解决方案,但有点别扭,希望有更简单的方法:
val cols = dataset.columns
val columnsToSelect = dataset
// count null values (by summing up 1s if its null)
.select(cols.map(c => (sum(when(col(c).isNull,1))>0).alias(c)):_*)
.head() // collect result of aggregation
.getValuesMap[Boolean](cols) // now get columns which are "true"
.filtercase (c,hasNulls) => hasNulls
.keys.toSeq // and get the name of those columns
dataset
.select(columnsToSelect.head,columnsToSelect.tail:_*)
.show()
+-------+----+
|country|hour|
+-------+----+
| null| 18|
| CA|null|
| NZ| 15|
+-------+----+
【讨论】:
感谢您的回答。事实上,我也期望有一种更简单的方法来实现它。你的回答比 mtoto 的回答要快。【参考方案2】:对this answer稍作修改,将每列的计数与行数进行比较:
import org.apache.spark.sql.functions.count,col
// Get number of rows
val nr_rows = dataset.count
// Get column indices
val col_inds = dataset.select(dataset.columns.map(c => count(col(c)).alias(c)): _*)
.collect()(0)
.toSeq.zipWithIndex
.filter(_._1 != nr_rows).map(_._2)
// Subset column names using the indices
col_inds.map(i => dataset.columns.apply(i))
Seq[String] = ArrayBuffer(country, hour)
【讨论】:
你多次调用dataset.count
效率很低以上是关于Spark 仅获取具有一个或多个空值的列的主要内容,如果未能解决你的问题,请参考以下文章