是否有办法删除仅包含空值的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)