【问题标题】:Create new matrix with all non-zero elements set to ones (julia)创建所有非零元素设置为一的新矩阵(朱莉娅)
【发布时间】:2021-05-18 21:54:59
【问题描述】:

我想要一种有效的(矢量化)方法将 julia 中的矩阵操作为新矩阵,其中所有非零元素都是新矩阵中的元素。

例如,我想要这个矩阵

0 3 6 8 0
7 0 2 0 1
0 4 9 1 0

成为

0 1 1 1 0
1 0 1 0 1
0 1 1 1 0

【问题讨论】:

  • 在 Julia 中高效不等于矢量化。循环很快。

标签: matrix julia linear-algebra


【解决方案1】:

最简单的方法是将此矩阵转换为BitMatrix 矩阵,如下所示:

julia> x = [0 3 6 8 0
            7 0 2 0 1
            0 4 9 1 0]
3×5 Matrix{Int64}:
 0  3  6  8  0
 7  0  2  0  1
 0  4  9  1  0

julia> x .!= 0
3×5 BitMatrix:
 0  1  1  1  0
 1  0  1  0  1
 0  1  1  1  0

如果您希望矩阵包含 Int 值,那么您可以这样做:

julia> Int.(x .!= 0)
3×5 Matrix{Int64}:
 0  1  1  1  0
 1  0  1  0  1
 0  1  1  1  0

最后,如果您的 0 值具有混合类型,并且您希望“按原样”保留它们,那么您可以这样做:

julia> x = Real[0   3 6 8 UInt8(0)
                7   0 2 0 1
                0.0 4 9 1 0]
3×5 Matrix{Real}:
 0    3  6  8  0x00
 7    0  2  0     1
 0.0  4  9  1     0

julia> @. ifelse(iszero(x), x, 1)
3×5 Matrix{Real}:
 0    1  1  1  0x00
 1    0  1  0     1
 0.0  1  1  1     0

除了广播之外,您还可以使用理解,这也应该很快。例如。

julia> [v == 0 ? v : 1 for v in x]
3×5 Matrix{Real}:
 0    1  1  1  0x00
 1    0  1  0     1
 0.0  1  1  1     0

或例如

julia> [ifelse(v == 0, 0, 1) for v in x]
3×5 Matrix{Int64}:
 0  1  1  1  0
 1  0  1  0  1
 0  1  1  1  0

【讨论】:

  • 非常感谢!我试过 x > 0 但我发现我错过了点运算符 (x .> 0)。
【解决方案2】:

尚未提及的替代方法是使用map

julia> x = [0 3 6 8 0
            7 0 2 0 1
            0 4 9 1 0]
3×5 Matrix{Int64}:
 0  3  6  8  0
 7  0  2  0  1
 0  4  9  1  0

julia> map(!=(0), x)
3×5 Matrix{Bool}:
 0  1  1  1  0
 1  0  1  0  1
 0  1  1  1  0

注意!=(0) 等同于y -> y != 0

正如另一个答案所示,广播布尔值函数的结果是BitMatrix。使用map 可以避免这种情况。

如果您想要一个产生与输入相同类型的“0”和“1”的解决方案:

julia> map(y -> ifelse(y == zero(y), one(y), zero(y)), x)
3×5 Matrix{Int64}:
 1  0  0  0  1
 0  1  0  1  0
 1  0  0  0  1

julia> map(y -> ifelse(y == zero(y), one(y), zero(y)), Float64.(x))
3×5 Matrix{Float64}:
 1.0  0.0  0.0  0.0  1.0
 0.0  1.0  0.0  1.0  0.0
 1.0  0.0  0.0  0.0  1.0

【讨论】:

  • 是的,map 是另一种选择。 Matrix{Bool}BitMatrix 之间的选择取决于用例,但 AFAICT BitMatrix 通常是首选,因为它的内存占用要小得多。请注意,像 [v != 0 for v in x] 这样的理解也会产生 Matrix{Bool}
  • BitMatrix 在某些情况下可能会更慢,并且与Matrix{Bool} 不同,如果多个线程正在写入数组,可能会引入竞争条件。
  • 没错——这就是我所说的取决于用例的意思。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 2014-04-26
  • 1970-01-01
相关资源
最近更新 更多