Hi, I’m a bit lost with the following simple exercise. I was wondering what would be the most efficient way to achieve this.
Suppose I have zeros(5,3,2), which returns the following.
5×3×2 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
[:, :, 2] =
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
I want to change the third column of each matrix by its index of the third array likewise :
A = zeros(5,3,2)
5×3×2 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
[:, :, 2] =
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
I wondered if there is a similar syntax to A[any, any,1] .= 1
and if vcat(A[:,:,1],A[:,:,2])
could be a fast way to get the following final result.
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
0.0 0.0 1
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
0.0 0.0 2
I think a for
loop is probably simplest for this.
julia> x = zeros(5,3,2);
julia> for k in axes(x,3)
x[:,end,k] .= k
end
julia> x
5×3×2 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
[:, :, 2] =
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
I don’t fully comprehend your last question, but you can achieve your last result using
julia> reduce(vcat,eachslice(x,dims=3))
10×3 Matrix{Float64}:
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
It seems like it might have been simpler to have used a 2-vector of 5x3 matrices to begin with. Unlike MATLAB, NumPy, and some other platforms, it isn’t necessary to vectorize operations to get fast code when using Julia.
You also could assemble your final matrix directly like
julia> y = zeros(10,3);
julia> for i in axes(y,1)
y[i,end] = div(i-1,5)+1
end
julia> y
10×3 Matrix{Float64}:
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
3 Likes
mkitti
June 30, 2023, 7:50am
3
You can construct the first result via the following.
julia> [1,1,1,1,1] .* [0;; 0;; 1] .* [1. ;;; 2]
5×3×2 Array{Float64, 3}:
[:, :, 1] =
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
0.0 0.0 1.0
[:, :, 2] =
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
0.0 0.0 2.0
Here is another way to construct the second result.
julia> [(I[2]==3)*(1 + (I[1] > 5)) for I in CartesianIndices((10,3))]
10×3 Matrix{Int64}:
0 0 1
0 0 1
0 0 1
0 0 1
0 0 1
0 0 2
0 0 2
0 0 2
0 0 2
0 0 2
2 Likes
Thank you very much for the suggestion. I didn’t know the usage of ;; and ;;;. It’s awesome!
Thank you very much. It workers slightly faster with your suggested version. I’ll use it.