Как вы предлагаете, вы можете разбить столбец Y, а затем использовать окно поверх идентификатора, чтобы вычислить всю интересующую вас статистику. Тем не менее, вы хотите потом повторно объединить свои данные, чтобы вы могли получить огромный промежуточный результат бесплатно.,
Spark не имеет много предопределенных функций для массивов.Поэтому, вероятно, самый простой способ добиться того, чего вы хотите - это UDF:
val extractFeatures = udf( (x : Seq[Int]) => {
val mean = x.sum.toDouble/x.size
val variance = x.map(i=> i*i).sum.toDouble/x.size - mean*mean
val std = scala.math.sqrt(variance)
Map("count" -> x.size.toDouble,
"mean" -> mean,
"std" -> std,
"min" -> x.min.toDouble,
"max" -> x.max.toDouble)
})
val df = sc
.parallelize(Seq((1,Seq(1,2,3,4,5)), (2,Seq(1,2,1,4))))
.toDF("id", "y")
.withColumn("described_y", extractFeatures('y))
.show(false)
+---+---------------+---------------------------------------------------------------------------------------------+
|id |y |described_y |
+---+---------------+---------------------------------------------------------------------------------------------+
|1 |[1, 2, 3, 4, 5]|Map(count -> 5.0, mean -> 3.0, min -> 1.0, std -> 1.4142135623730951, max -> 5.0, var -> 2.0)|
|2 |[1, 2, 1, 4] |Map(count -> 4.0, mean -> 2.0, min -> 1.0, std -> 1.224744871391589, max -> 4.0, var -> 1.5) |
+---+---------------+---------------------------------------------------------------------------------------------+
И, кстати, вычисленный вами stddev на самом деле является дисперсией.Вам нужно взять квадратный корень, чтобы получить стандартное отклонение.