Apache spark 使用explode和Descripte函数触发数据帧
我有一个spark数据框,它有3列(id:Int、x_轴:Array[Int]、y_轴:Array[Int]),下面是一些示例数据: 要获取数据帧中每行y_轴列的基本统计信息。输出类似于: 我尝试过分解然后描述,但无法计算出预期的输出。Apache spark 使用explode和Descripte函数触发数据帧,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我有一个spark数据框,它有3列(id:Int、x_轴:Array[Int]、y_轴:Array[Int]),下面是一些示例数据: 要获取数据帧中每行y_轴列的基本统计信息。输出类似于: 我尝试过分解然后描述,但无法计算出预期的输出。 任何帮助或参考都非常有用正如您所建议的,您可以分解Y列,然后使用id上的窗口来计算您感兴趣的所有统计信息。尽管如此,您还是希望在事后重新聚合数据,以便免费生成一个巨大的中间结果 Spark没有很多用于阵列的预定义函数。因此,实现您想要的最简单的方法可能是UD
任何帮助或参考都非常有用正如您所建议的,您可以分解Y列,然后使用id上的窗口来计算您感兴趣的所有统计信息。尽管如此,您还是希望在事后重新聚合数据,以便免费生成一个巨大的中间结果 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) |
+---+---------------+---------------------------------------------------------------------------------------------+
顺便说一句,你计算的STDEV实际上是方差。您需要取平方根才能得到标准偏差。感谢您建议使用UDF的这种方法。spark DataFrames提供了一个名为“descripe”的函数,用于获取基本统计数据并返回新的DF。想知道我们是否可以用它来代替我们的UDF逻辑。我的缺点是stddev的值不正确。据我所知,Spark的descripe函数用于计算给定数据帧的整列统计数据,在windows上没有简单的计算方法。无论如何使用descripe的一个技巧是将数据帧拆分为K个数据帧,K是不同ID的数量。然而,这完全违背了Spark的精神,而且会非常昂贵,因此我明确建议使用UDF方法。