假设我有以下数据框:
/*
+---------+--------+----------+--------+
|a |b | c |d |
+---------+--------+----------+--------+
| bob| -1| 5| -1|
| alice| -1| -1| -1|
+---------+--------+----------+--------+
*/
我想删除所有行中只有-1
的列(在本例中为b
和d
)。我找到了一个解决方案,但是当我开始工作时,我发现它的效率很低:
private def removeEmptyColumns(df: DataFrame): DataFrame = {
val types = List("IntegerType", "DoubleType", "LongType")
val dTypes: Array[(String, String)] = df.dtypes
dTypes.foldLeft(df)((d, t) => {
val colType = t._2
val colName = t._1
if (types.contains(colType)) {
if (colType.equals("IntegerType")) {
if (d.select(colName).filter(col(colName) =!= -1).take(1).length == 0) d.drop(colName)
else d
} else if (colType.equals("DoubleType")) {
if (d.select(colName).filter(col(colName) =!= -1.0).take(1).length == 0) d.drop(colName)
else d
} else {
if (d.select(colName).filter(col(colName) =!= -1).take(1).length == 0) d.drop(colName)
else d
}
} else {
d
}
})
}
是否有更好的解决方案或方法来改进我现有的代码?
(我认为这一行val count = d.select(colName).distinct.count
是瓶颈)
我正在使用Spark 2.2 atm。
非常感谢
答案 0 :(得分:0)
不要计算不同值的数量,而是尝试检查是否存在任何其他不是-1
的值
d.select(colName).filter(_ != -1).take(1).length == 0
另一种方法
您可以尝试一次性收集统计信息,而不是遍历数据框n次(每列一次)
val summary = d.agg(
max(col1).as(s"${col1}_max"), min(col1).as(s"${col1}_min")),
max(col2).as(s"${col1}_max"), min(col2).as(s"${col2}_min")),
...)
.first
然后比较该列的min
和max
值是否相同-1