【问题标题】:Vector product using map and reduce in scala在scala中使用map和reduce的向量积
【发布时间】:2017-05-01 00:42:24
【问题描述】:

我正在尝试使用 map 和 reduce 函数计算两个向量之间的向量积。

让我们看看 Scala 的 REPL 中发生了什么:

首先我定义了两个长度相同的向量

scala> val v1 = Array(1,4,5,2)
v1: Array[Int] = Array(1, 4, 5, 2)

scala> val v2 = Array (3,5,1,5)
v2: Array[Int] = Array(3, 5, 1, 5)

现在我使用 zip 函数创建一个新数组 vecZip

scala> val vecZip = v1 zip v2
vecZip: Array[(Int, Int)] = Array((1,3), (4,5), (5,1), (2,5))

现在我想应用 reduce 方法 (做每个元组的乘积)这个数组的每个元素。 我是这么想的:

val vecToSum = vecZip.map(x=>(List(x).reduce(_*_))) 

我想得到一个列表 (vecToSum),在其中应用 reduce 方法来计算总结果。但是我收到此错误:

scala>  val vecToSum = vecZip.map(x=>(List(x).reduce(_*_)))
<console>:10: error: value * is not a member of (Int, Int)
    val vecToSum = vecZip.map(x=>(List(x).reduce(_*_)))
                                                  ^

【问题讨论】:

    标签: scala dictionary vector reduce


    【解决方案1】:

    你不需要在这里减少。减少Array[(Int, Int)] 意味着对数组内的所有元组执行一些关联的二进制操作。请注意,它可能对前一对元组执行操作,然后对那个和第三个元组的结果,然后对那个和第四个元组的结果等执行操作,但由于关联性,它可以执行操作在第一个和第二个元组上,同时在第三个和第四个元组上,然后是它们的结果等,这对于并行化很好(Spark 等框架严重依赖它))。

    例如,您可以将每个元组的所有第一个元素和所有第二个元素相加:

    val reduced = vecZip.reduce((pair1, pair2) => (pair1._1 + pair2._1, pair1._2 + pair2._2))
    

    然而,你想要的是简单地将每个元组映射到其元素的乘积:

    val vecToSum = vecZip.map { case (x, y) => x * y }
    

    请注意,我使用了偏函数(参见那边的case)来对元组执行模式匹配;如果没有偏函数,它看起来像这样:

    val vecToSum = vecZip.map(tuple => tuple._1 * tuple._2)
    

    【讨论】:

      【解决方案2】:

      您的代码实际上试图做的是创建一个包含单个元组元素的列表,然后尝试减少它。它永远不会以这种方式工作,因为没有什么可以减少 - 列表中已经有一个元素 - 一个元组。

      相反,您需要通过乘以它们的元素来映射您的 vecZip 数组元素(元组):

      vecZip.map { case (x, y) => x * y }
      

      【讨论】:

        【解决方案3】:

        您只需要调用 map 并将元组值相乘,如下所示:

        val vecToSum = vecZip.map(x => x._1 * x._2) 
        

        vecToSum 是一个元组列表,所以x 是一个(Int, Int) 的元组。因此,如果您调用List(x).reduce(...),您将创建一个唯一值是元组的列表,所以这并不是您真正想要的。

        【讨论】:

        • 我收到此错误:scala> val vecToSum = vecZip.map(x=>x_.1 * x_.2) :1: error: ')' 预期但发现双字。 val vecToSum = vecZip.map(x=>x_.1 * x_.2) ^
        • 你打错字了 :) 应该是 x._1 而不是 x_.1
        • 非常感谢!
        猜你喜欢
        • 2020-09-17
        • 2016-11-05
        • 1970-01-01
        • 2022-01-08
        • 1970-01-01
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        相关资源
        最近更新 更多