查找大型数据集的均值和标准差

时间:2014-06-12 19:17:39

标签: scala apache-spark

我在S3上有大约1500个文件(每个文件看起来像这样:)

格式:
UserId \ t ItemId:Score,ItemdId:Score,ItemId:Score \ n
UserId \ t ItemId:Score,ItemdId:Score,ItemId:Score \ n

我将文件读作:

import scala.io.Source
val FileRead = Source.fromFile("/home/home/testdataFile1").mkString 

以下是我得到的一个例子:

1152 401368:1.006,401207:1.03
1184 401230:1.119,40049:1.11,40029:1.31

如何计算变量'得分'

的平均值和标准差

4 个答案:

答案 0 :(得分:13)

虽然问题中没有明确说明,Apache Spark是以分布式方式执行此操作的好工具。我假设你已经建立了一个Spark集群。将文件读入RDD:

val lines: RDD[String] = sc.textFile("s3n://bucket/dir/*")

以某种方式挑出“得分”:

val scores: RDD[Double] = lines.map(_.split(":").last.toDouble).cache

.cache将其保存在内存中。这样可以避免一直重新读取文件,但可以使用大量的RAM。如果你想换取RAM的速度,请将其删除。

计算指标:

val count = scores.count
val mean = scores.sum / count
val devs = scores.map(score => (score - mean) * (score - mean))
val stddev = Math.sqrt(devs.sum / (count - 1))

答案 1 :(得分:1)

我使用Apache Commons Math来处理这些东西(http://commons.apache.org/proper/commons-math/userguide/stat.html),尽管来自Java。您可以通过SummaryStatistics类来传输内容,这样您就不会受到内存大小的限制。 Scala到Java互操作应该允许你这样做,但我还没有尝试过。您应该能够逐行浏览文件,并通过SummaryStatistics实例流式传输内容。 Scala有多难?

在这里看,有人离开了,并且整个事情都在进行:https://code.google.com/p/scalalab/wiki/ApacheCommonMathsLibraryInScalaLab

答案 2 :(得分:1)

这个问题并不新鲜,所以也许我可以更新答案。

stddev函数(stddevstddev_popstddev_smap)是SparkSQL(import org.apache.spark.sql.functions),因为spark版本> = 1.6.0。

答案 3 :(得分:0)

我不认为存储空间应该是一个问题所以我会尝试将所有值放入一个双打数组中,然后将所有值相加然后使用它和数组中的元素数量然后计算平均值。然后将平均值中的差值的所有绝对值相加,并除以元素数量。然后取平方根。