代码之家  ›  专栏  ›  技术社区  ›  samba

如何找到火花RDD的平均值?

  •  -1
  • samba  · 技术社区  · 6 年前

    我读过reduce函数必须是交换的和关联的。我应该如何编写一个函数来查找平均值,使其符合此要求?如果我应用以下函数来计算RDD的平均值,那么它将无法正确计算平均值。有人能解释一下我的功能出了什么问题吗?
    我想它需要两个元素,比如1,2,然后像(1+2)/2那样对它们应用函数。然后将结果与下一个元素3相加,再除以2等。

    val rdd = sc.parallelize(1 to 100)
    
    rdd.reduce((_ + _) / 2)
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   chubock    6 年前

    你也可以使用 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
    
        2
  •  2
  •   Leo C    6 年前

    RDD.减少((+)/2)

    上面有几个问题 reduce 平均计算方法:

    1. 这个 placeholder 语法不能作为 reduce((acc, x) => (acc + x) / 2)
    2. 因为您的rdd是integer类型, rdd.reduce((acc, x) => (acc + x) / 2) 会导致 integer division 在每次迭代中(计算平均值肯定不正确)
    3. 这个 减少 方法不会生成列表的平均值。例如:

      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(_ + _) 若要对列表求和,请将总和除以其大小,如下所示:

    rdd.reduce(_ + _) / rdd.count.toDouble
    

    但是您可以简单地使用rdd的内置函数 mean 以下内容:

    rdd.mean