【问题标题】:Spark Scala SQL: Take average of non-null columnsSpark Scala SQL:取非空列的平均值
【发布时间】:2020-04-15 19:58:07
【问题描述】:
如何对数组cols 中的列与数据框df 中的非空值取平均值?我可以对 all 列执行此操作,但是当任何值为 null 时它会给出 null。
val cols = Array($"col1", $"col2", $"col3")
df.withColumn("avgCols", cols.foldLeft(lit(0)){(x, y) => x + y} / cols.length)
我不想na.fill,因为我想保留真实的平均值。
【问题讨论】:
标签:
scala
apache-spark
apache-spark-sql
【解决方案1】:
我猜你可以这样做:
val cols = Array("col1", "col2", "col3")
def countAvg =
udf((data: Row) => {
val notNullIndices = cols.indices.filterNot(i => data.isNullAt(i))
notNullIndices.map(i => data.getDouble(i)).sum / notNullIndices.lenght
})
df.withColumn("seqNull", struct(cols.map(col): _*))
.withColumn("avg", countAvg(col("seqNull")))
.show(truncate = false)
但要小心,这里的平均值只计算非空元素。
如果您需要代码中的完全解决方案:
val cols = Array("col1", "col2", "col3")
def countAvg =
udf((data: Row) => {
val notNullIndices = cols.indices.filterNot(i => data.isNullAt(i))
notNullIndices.map(i => data.getDouble(i)).sum / cols.lenght
})
df.withColumn("seqNull", struct(cols.map(col): _*))
.withColumn("avg", countAvg(col("seqNull")))
.show(truncate = false)