【问题标题】:How to replace elements of a breeze matrix in Scala based on some condition?如何根据某些条件替换Scala中微风矩阵的元素?
【发布时间】:2017-09-03 12:00:47
【问题描述】:

我正在使用 Scala 中的二维 Breeze 矩阵。在某些时候,我必须对两个矩阵进行逐元素除法。分母矩阵中的某些元素可能为零,从而导致结果中的 NaN。

我可以遍历矩阵维度并将 0.0 替换为 >0。

但是有没有更简单或 Scala 惯用的解决方案呢?

【问题讨论】:

    标签: scala apache-spark scala-breeze


    【解决方案1】:

    一步一步:

    • 带有示例矩阵:

      val dm = DenseMatrix((1.0, 0.0, 3.0), (0.0, 5.0, 6.0))
      
    • 找出哪些元素等于0.0:

      dm :== 0.0
      
      breeze.linalg.DenseMatrix[Boolean] =
      false  true   false
      true   false  false
      
    • 对矩阵进行切片:

      dm(dm :== 0.0)
      
      breeze.linalg.SliceVector[(Int, Int),Double] = breeze.linalg.SliceVector@2b
      
    • 使用切片矩阵进行替换:

      dm(dm :== 0.0) := 42.0
      
      breeze.linalg.Vector[Double] = breeze.linalg.SliceVector@2b
      
    • 检查矩阵:

      dm
      
      breeze.linalg.DenseMatrix[Double] =
      1.0   42.0  3.0
      42.0  5.0   6.0
      

    【讨论】:

    • 谢谢!这就是我一直在寻找的。​​span>
    • @inferno 我很高兴听到这个消息。如果我建议accepting 和/或upvoting 回答,我希望你不会介意。提前致谢。
    【解决方案2】:

    映射出NaN 比切片更快。

    val matr = DenseMatrix((1.0, 0.0, 3.0), (0.0, 11.0, 12.0),
          (1.0, 2.0, 0.0))
    val matr2 = DenseMatrix((3.0, 0.0, 1.0), (0.0, 12.0, 11.0),
          (2.0, 1.0, 0.0))
    
    def time[R](block: => R): R = {
      val t0 = System.nanoTime()
      val result = block    // call-by-name
      val t1 = System.nanoTime()
      println("Elapsed time: " + (t1 - t0) + "ns")
      result
    }
    
    def replaceZeroes1(mat1: DenseMatrix[Double], mat2: DenseMatrix[Double], rep: Double) = {
       (mat1 /:/ mat2).map(x => if (x.isNaN()) rep else x)
    }
        
    def replaceZeroes2(mat1: DenseMatrix[Double], mat2: DenseMatrix[Double], rep: Double) = {
        mat1(mat1 :== 0.0) := rep
        mat2(mat2 :== 0.0) := 1
        mat1 /:/ mat2
    }
    time(println(replaceZeroes1(matr, matr2, 42.0)))
    time(println(replaceZeroes2(matr, matr2, 42.0)))
    

    生产:

    0.3333333333333333  42.0                3.0                 
    42.0                0.9166666666666666  1.0909090909090908  
    0.5                 2.0                 42.0                
    Elapsed time: 13087782ns
    Replace Zero2
    0.3333333333333333  42.0                3.0                 
    42.0                0.9166666666666666  1.0909090909090908  
    0.5                 2.0                 42.0                
    Elapsed time: 16613179ns
    

    映射出 NaN 更快更直接。即使从 function2 中删除第二个切片也会更快。

    注意:这没有在 Spark 中使用非常大的数据集进行测试,只是轻而易举。在那种情况下,可能会有不同的时间(尽管我对此表示怀疑)。

    奖励:

    如果您只是尝试从具有任何值集的矩阵生成 1 和 0 矩阵(例如从加权网络生成非加权网络),我会使用:

    (mat /:/ mat).map(x => if (x.isNaN()) 0.0 else x)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-25
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多