用于仅选择包含至少一个非空值的列的惯用法

时间:2018-01-26 15:05:09

标签: scala apache-spark apache-spark-sql

仅选择那些包含至少一个NOT NULL值的DataFrame / DataSet列的最惯用(和有效)方法是什么。

即。拥有以下数据集:

+----+----+------+----+---------------------+----+
|int1|int2|str1  |str2|dt1                  |dt2 |
+----+----+------+----+---------------------+----+
|1   |null|strin1|null|null                 |null|
|null|null|null  |null|2000-01-03 12:12:12.0|null|
+----+----+------+----+---------------------+----+

我将如何获得以下内容:

+----+------+---------------------+
|int1|str1  |dt1                  |
+----+------+---------------------+
|1   |strin1|null                 |
|null|null  |2000-01-03 12:12:12.0|
+----+------+---------------------+

有一个适用于Apache Spark版本1.6.0 +

的解决方案会很不错

数据设置:

case class C(int1: Integer, int2: Integer, str1: String, str2: String, dt1: String, dt2: String)

val cc = Seq(
  C(1, null, "strin1", null, null, null),
  C(null, null, null, null, "2000-01-03 12:12:12", null)
)
val t = sc.parallelize(cc, 2).toDF()
val df = t.withColumn("dt1", $"dt1".cast("timestamp")).withColumn("dt2", $"dt2".cast("timestamp"))

更新

PS感谢@user8371915指向very similar question。我想打开这个问题,希望找到一个更优雅的解决方案 - 我试图找到一种方法来使用类似的东西:

df.columns.filter(c => when(count(col(c))>0,c))

但我无法弄清楚如何正确地做到这一点......

1 个答案:

答案 0 :(得分:1)

使用an approach very similar to one described in this great answer

val cols = df.select(df.columns.map(c => count(col(c)).alias(c)): _*)
             .collect()(0)
             .toSeq.zipWithIndex
             .filter(_._1 != 0).map(_._2)
             .map(i => df.columns.apply(i))

这为我们提供了一系列我们正在寻找的列:

scala> cols
res125: Seq[String] = ArrayBuffer(int1, str1, dt1)

现在我们可以选择这些列:

scala> df.select(cols.head, cols.tail: _*).show
+----+------+--------------------+
|int1|  str1|                 dt1|
+----+------+--------------------+
|   1|strin1|                null|
|null|  null|2000-01-03 12:12:...|
+----+------+--------------------+

scala> df.select(cols.map(col): _*).show
+----+------+--------------------+
|int1|  str1|                 dt1|
+----+------+--------------------+
|   1|strin1|                null|
|null|  null|2000-01-03 12:12:...|
+----+------+--------------------+