Indexing 使用数组进行数组内索引

Indexing 使用数组进行数组内索引,indexing,julia,Indexing,Julia,有更好的方法吗 a = rand(10,10) a[[CartesianIndex(i,i) for i in 1:10]] .= something 即使用setindex!没有CartesianIndex或类似的 a[i,i for i in 1:10] .= something 或者通常使用setindex

有更好的方法吗

a = rand(10,10)
a[[CartesianIndex(i,i) for i in 1:10]] .= something
即使用setindex!没有
CartesianIndex
或类似的

a[i,i for i in 1:10] .= something

或者通常使用
setindex我喜欢
CartesianIndex
解决方案,但另一种方法是创建布尔掩码:

julia> a = rand(5, 5);

julia> a[[i == j for i ∈ 1:5, j ∈ 1:5]] .= 0;

julia> a
5×5 Array{Float64,2}:
 0.0       0.376169  0.0248078  0.957535   0.522565
 0.116614  0.0       0.743684   0.0500792  0.704349
 0.728995  0.643491  0.0        0.367225   0.348022
 0.338079  0.451293  0.383365   0.0        0.111781
 0.602485  0.249625  0.963363   0.0850144  0.0

我只是想总结一下所有答案和评论,看看每个建议解决方案的性能

using LinearAlgebra, BenchmarkTools
A = rand(1000, 1000)
B  = [i == j for i ∈ 1:1000, j ∈ 1:1000]
B2 = BitArray(B)
CI = CartesianIndex.(1:1000, 1:1000)
step = size(A,1) +1
    
@btime A[[i == j for i ∈ 1:1000, j ∈ 1:1000]]
2.622 ms (3 allocations: 984.64 KiB)

@btime A[B]
1.806 ms (1 allocation: 7.94 KiB)

@btime A[(1:1000) .== (1:1000)']
509.597 μs (5 allocations: 134.38 KiB)

@btime A[B2]
35.067 μs (1 allocation: 7.94 KiB)

@btime A[[CartesianIndex(i,i) for i in 1:1000]]
6.051 μs (2 allocations: 23.69 KiB)

@btime A[CartesianIndex.(1:1000, 1:1000)]
5.769 μs (2 allocations: 23.69 KiB)

@btime A[CI]
4.093 μs (1 allocation: 7.94 KiB)

@btime A[1:size(A,1)+1:end]
2.123 μs (4 allocations: 8.00 KiB)

@btime A[1:step:end]
2.073 μs (3 allocations: 7.98 KiB)

@btime A[diagind(A)]
2.036 μs (2 allocations: 7.97 KiB)

使用线性索引是最快的解决方案,其中内置的
diagind
性能稍好。使用
CartesianIndices
访问非对角元素可能更容易,而且仍然表现得很好。

如果您只是想用一种较短的方式来编写,您也可以将其写成
a[CartesianIndex.(1:10,1:10)]。=something
如果对角线是您想要的,那么
a[diagind(a)]线性代数中的.=0
就是为此而设计的。这里是
1:11:100
即使用线性索引。等效地,
a[(1:5)。=(1:5)].=0
也应该工作,如果您喜欢广播。如果您想要性能代码,这不是一个好的解决方案,因为它必须在访问索引之前分配整个矩阵