Scala 如何找到Spark RDD的平均值?

Scala 如何找到Spark RDD的平均值?,scala,apache-spark,mapreduce,rdd,Scala,Apache Spark,Mapreduce,Rdd,我读过,reduce函数必须是交换的和结合的。我应该如何编写一个函数来查找平均值,使其符合此要求?如果我应用以下函数来计算RDD的平均值,它将无法正确计算平均值。谁能解释一下我的功能有什么问题吗 我猜它需要两个元素,比如1,2,并将函数应用于它们,比如(1+2)/2。然后将结果与下一个元素3相加并除以2,以此类推 val rdd = sc.parallelize(1 to 100) rdd.reduce((_ + _) / 2) rdd.reduce((+)/2) 上述reduce平均值计算

我读过,reduce函数必须是交换的和结合的。我应该如何编写一个函数来查找平均值,使其符合此要求?如果我应用以下函数来计算RDD的平均值,它将无法正确计算平均值。谁能解释一下我的功能有什么问题吗

我猜它需要两个元素,比如1,2,并将函数应用于它们,比如
(1+2)/2
。然后将结果与下一个元素3相加并除以2,以此类推

val rdd = sc.parallelize(1 to 100)

rdd.reduce((_ + _) / 2)
rdd.reduce((+)/2)

上述
reduce
平均值计算方法存在一些问题:

  • 占位符
    语法不能作为
    reduce((acc,x)=>(acc+x)/2)的简写
  • 由于您的RDD是整数类型,
    RDD.reduce((acc,x)=>(acc+x)/2)
    将在每次迭代中导致一个
    整数除法
    (计算平均值时肯定不正确)
  • reduce
    方法不会生成列表的平均值。例如:

    List[Double](1, 2, 3).reduce((a, x) => (a + x) / 2)
    --> (1.0 + 2.0) / 2 = 1.5
    --> (1.5 + 3.0) / 2 = 2.25
    Result: 2.25
    
    鉴于:

    Average of List[Double](1, 2, 3) = 2.0
    
  • 我应该如何编写[reduce]函数来查找平均值,使其符合此要求

    我不确定
    reduce
    是否适合直接计算列表的平均值。您当然可以使用
    reduce(+)
    对列表进行求和,然后将求和除以其大小,如:

    rdd.reduce(_ + _) / rdd.count.toDouble
    
    但是,您可以简单地使用RDD的内置函数
    mean

    rdd.mean
    
    rdd.reduce((+)/2)

    上述
    reduce
    平均值计算方法存在一些问题:

  • 占位符
    语法不能作为
    reduce((acc,x)=>(acc+x)/2)的简写
  • 由于您的RDD是整数类型,
    RDD.reduce((acc,x)=>(acc+x)/2)
    将在每次迭代中导致一个
    整数除法
    (计算平均值时肯定不正确)
  • reduce
    方法不会生成列表的平均值。例如:

    List[Double](1, 2, 3).reduce((a, x) => (a + x) / 2)
    --> (1.0 + 2.0) / 2 = 1.5
    --> (1.5 + 3.0) / 2 = 2.25
    Result: 2.25
    
    鉴于:

    Average of List[Double](1, 2, 3) = 2.0
    
  • 我应该如何编写[reduce]函数来查找平均值,使其符合此要求

    我不确定
    reduce
    是否适合直接计算列表的平均值。您当然可以使用
    reduce(+)
    对列表进行求和,然后将求和除以其大小,如:

    rdd.reduce(_ + _) / rdd.count.toDouble
    
    但是,您可以简单地使用RDD的内置函数
    mean

    rdd.mean
    

    您还可以使用
    PairRDD
    跟踪所有元素的总和以及元素的计数

    val pair = sc.parallelize(1 to 100)
    .map(x => (x, 1))
    .reduce((x, y) => (x._1 + y._1, x._2 + y._2))
    
    val mean = pair._1 / pair._2
    

    您还可以使用
    PairRDD
    跟踪所有元素的总和以及元素的计数

    val pair = sc.parallelize(1 to 100)
    .map(x => (x, 1))
    .reduce((x, y) => (x._1 + y._1, x._2 + y._2))
    
    val mean = pair._1 / pair._2