Spark scala删除只包含空值的列



是否有办法删除仅包含空值的spark dataFrame的列?(我使用scala和Spark 1.6.2)

此刻我正在做这个:

var validCols: List[String] = List()
for (col <- df_filtered.columns){
  val count = df_filtered
    .select(col)
    .distinct
    .count
  println(col, count)
  if (count >= 2){
    validCols ++= List(col)
  }
}

构建包含至少两个不同值的列的列表,然后在select()中使用它。

我有同样的问题,我在Java中提出了类似的解决方案。在我看来,目前没有别的办法。

for (String column:df.columns()){
    long count = df.select(column).distinct().count();
    if(count == 1 && df.select(column).first().isNullAt(0)){
        df = df.drop(column);
    }
}

我删除了所有只包含一个不同值且第一个值为null的列。这样我就可以确保我不删除列,所有的值都是相同的,但不是null。

下面是一个scala示例,用于删除只查询一次数据的空列(更快):

def removeNullColumns(df:DataFrame): DataFrame = {
    var dfNoNulls = df
    val exprs = df.columns.map((_ -> "count")).toMap
    val cnts = df.agg(exprs).first
    for(c <- df.columns) {
        val uses = cnts.getAs[Long]("count("+c+")")
        if ( uses == 0 ) {
            dfNoNulls = dfNoNulls.drop(c)
        }
    }
    return dfNoNulls
}

@swdev答案的更习惯的版本:

private def removeNullColumns(df:DataFrame): DataFrame = {
  val exprs = df.columns.map((_ -> "count")).toMap
  val cnts = df.agg(exprs).first
  df.columns
    .filter(c => cnts.getAs[Long]("count("+c+")") == 0)
    .foldLeft(df)((df, col) => df.drop(col))
}

如果数据框架的大小合理,我将其写入json,然后重新加载。动态模式将忽略空列,您将拥有更轻的数据框架。

scala代码片段:

originalDataFrame.write(tempJsonPath)
val lightDataFrame = spark.read.json(tempJsonPath)

以下是pySpark语法中的@tim -strotmann解决方案:

for column in df.columns:
    count = df.select(column).distinct().count()
    if count == 1 and df.first()[column] is None:
        df = df.drop(column)

相关内容

  • 没有找到相关文章

最新更新