删除Spark SQL中的NULL列

时间:2017-07-26 10:49:29

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

如何从表中删除仅包含空值的列?假设我有一张桌子 -

SnapshotDate    CreationDate    Country Region  CloseDate   Probability BookingAmount   RevenueAmount   SnapshotDate1   CreationDate1   CloseDate1
        null            null       null   null       null   25  882000  0            null            null         null
        null            null       null   null       null   25  882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null
        null            null       null   null       null   0   882000  0            null            null         null

所以我只想拥有Probability,BookingAmount和RevenueAmount列并忽略其余部分。

有没有办法动态选择列?

我正在使用spark 1.6.1

2 个答案:

答案 0 :(得分:1)

我用全球groupBy解决了这个问题。这适用于数字和非数字列:

case class Entry(id: Long, name: String, value: java.lang.Float)

val results = Seq(
  Entry(10, null, null),
  Entry(10, null, null),
  Entry(20, null, null)
)

val df: DataFrame = spark.createDataFrame(results)

// mark all columns with null only
val row = df
  .select(df.columns.map(c => when(col(c).isNull, 0).otherwise(1).as(c)): _*)
  .groupBy().max(df.columns.map(c => c): _*)
  .first

// and filter the columns out
val colKeep = row.getValuesMap[Int](row.schema.fieldNames)
  .map{c => if (c._2 == 1) Some(c._1) else None }
  .flatten.toArray
df.select(row.schema.fieldNames.intersect(colKeep)
  .map(c => col(c.drop(4).dropRight(1))): _*).show(false)

+---+
|id |
+---+
|10 |
|10 |
|20 |
+---+

编辑:我删除了列的改组。新方法保持列的给定顺序。

答案 1 :(得分:-1)

您可以在Spark SQL中添加自定义udf。

sqlContext.udf.register("ISNOTNULL", (str: String) => Option(str).getOrElse(""))

使用Spark SQL,您可以:

SELECT ISNOTNULL(Probability) Probability, ISNOTNULL(BookingAmount) BookingAmount, ISNOTNULL(RevenueAmount) RevenueAmount FROM df