Matrix 创建所有非零元素都设置为1的新矩阵(julia)

Matrix 创建所有非零元素都设置为1的新矩阵(julia),matrix,julia,linear-algebra,Matrix,Julia,Linear Algebra,我想要一种有效的(矢量化的)方法,将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> x = [0 3 6 8 0 7 0 2 0 1 0 4 9 1 0] 3×5 Matrix{Int64}: 0

我想要一种有效的(矢量化的)方法,将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> 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
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
最后,如果您的
0
值具有混合类型,并且您希望“按原样”保留它们,那么您可以执行以下操作:

julia> Int.(x .!= 0)
3×5 Matrix{Int64}:
 0  1  1  1  0
 1  0  1  0  1
 0  1  1  1  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

尚未提及的另一种方法是使用
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

另一个答案显示,广播布尔值函数的结果是
位矩阵
。使用
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

非常感谢!我尝试了x>0,但是我发现我错过了点运算符(x>0)。效率不等于Julia中的向量化。循环很快。是的,
map
是另一个选项。在
矩阵{Bool}
位矩阵
之间的选择取决于用例,但AFAICT
位矩阵
通常是首选的,因为它具有更小的内存占用。请注意,像
[v!=0表示x中的v]
这样的理解也会产生
矩阵{Bool}
位矩阵
在某些情况下可能较慢,并且与
矩阵{Bool}
不同,如果多个线程写入数组,可能会引入竞争条件。确切地说,这就是我所说的它取决于用例的意思。