Spark Scala SQL: взять среднее значение для ненулевых столбцов - PullRequest
0 голосов
/ 15 апреля 2020

Как взять среднее значение столбцов в массиве cols с ненулевыми значениями в кадре данных df? Я могу сделать это для всех столбцов, но это дает ноль, когда любое из значений равно нулю.

val cols = Array($"col1", $"col2", $"col3")
df.withColumn("avgCols", cols.foldLeft(lit(0)){(x, y) => x + y} / cols.length)

Я не хочу na.fill, потому что я хочу сохранить истинное средний.

1 Ответ

1 голос
/ 15 апреля 2020

Я думаю, вы можете сделать что-то вроде этого:

    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)
...