【问题标题】:Sum of arrays elementwise using Spark Scala使用 Spark Scala 对数组元素求和
【发布时间】:2021-07-05 22:03:20
【问题描述】:

我正在尝试在 Spark Scala 中实现 Kmeans 聚类。

所以目前我有一个看起来像这样的 RDD- 它包含聚类中心和数据点。

scala> res2.collect
res54: Array[(Int, Array[Any])] = Array((2,Array(19, 15, 39)), (2,Array(21, 15, 81)), (2,Array(20, 16, 6)), (1,Array(23, 16, 77)), (2,Array(31, 17, 40)), (3,Array(22, 17, 76)), (1,Array(35, 18, 6)), (3,Array(23, 18, 94)), (1,Array(64, 19, 3)), (1,Array(30, 19, 72)))

我的下一步是根据数组的键对数组进行元素求和,然后将结果除以计数(通过平均来找到新的质心集)。

我不知道如何实现这一点,因为简单地使用 reduceByKey(__+_) 不适用于数组。

【问题讨论】:

    标签: scala apache-spark rdd


    【解决方案1】:

    ReduceByKey 应该适用于数组。通过计数,我假设您的意思是与给定键关联的元素数,可以使用 countByKey() 找到。这种方法应该有效:

    val keycount = your_rdd.countByKey()
    def reduceSum(a1: Array[Int], a2: Array[Int]): Array[Int] = {
      Array(a1(0)+a2(0),a1(1)+a2(1),a1(2)+a2(2))
    }
    val summed = your_rdd.reduceByKey(reduceSum)
    val combined = keycount.join(summed)
    combined.map{
      case (idx, (count, arr)) => arr.map(1.0*arr / count) 
    }
    

    【讨论】:

    • 您好,感谢您的解决方案。所以实际上我的数组长度为 100。在这种情况下我该怎么办?我将不得不写一个for循环对吗?有更简单的解决方案吗?
    • a1.zip(a2).map{ case(a,b) => a+b }
    【解决方案2】:

    这是我的解决方案:

    import spark.implicits._
    
      val df = spark.sparkContext.parallelize(Array((2,Array(19, 15, 39)), (2,Array(21, 15, 81)), (2,Array(20, 16, 6)), (1,Array(23, 16, 77)), (2,Array(31, 17, 40)), (3,Array(22, 17, 76)), (1,Array(35, 18, 6)), (3,Array(23, 18, 94)), (1,Array(64, 19, 3)), (1,Array(30, 19, 72))))
    
      df.map(line => {
    
        val sumValues = line._2.sum/line._2.size;
    
        (line._1, sumValues)
    
      } ).reduceByKey(_+_).toDF("key","avg").show();
    

    输出

    |key|avg|
    +---+---+
    |  1|125|
    |  3| 83|
    |  2|106|
    +---+---+
    

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 2019-10-25
      相关资源
      最近更新 更多