Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.8k views
in Technique[技术] by (71.8m points)

Julia, use findall to reset a third row in a 3d array

I'm attempting to use findall to get an index of which elements of one 1d array are greater than those of a second 1d array, and then use those indexes to set corresponding values of a third 1d array to 0. MWE:

# create 3d array
a, b = [3;2;2], [4;3;2];
c = transpose(cat(a,b, dims = 2));
d, e = [1;2;3], [2;3;4];
f = transpose(cat(d,e, dims = 2));
g = cat(c, f, dims = 3);

g
2×3×2 Array{Int64,3}:
[:, :, 1] =
 3  2  2
 4  3  2

[:, :, 2] =
 1  2  3
 2  3  4

findall.(g[end,:,1] >= g[end-1,:,1]) 

and use indexes to reset elements of g[end,:,2] such that I end up with

g
2×3×2 Array{Int64,3}:
[:, :, 1] =
 3  2  2
 4  3  2

[:, :, 2] =
 1  2  3
 0  0  4

Thx. J


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The code below gives the answer you request. You just have the . in the wrong spot. You want to compare the > operation element by element, and then apply findall to the entire resulting array (not element by element).

julia> g[end, findall(g[end,:,1] .> g[end-1,:,1]), 2] .= 0
2-element view(::Array{Int64,3}, 2, [1, 2], 2) with eltype Int64:
 0
 0

julia> g
2×3×2 Array{Int64,3}:
[:, :, 1] =
 3  2  2
 4  3  2

[:, :, 2] =
 1  2  3
 0  0  4

However, I wouldn't try to compile all your data into one big array like that. It would be easier to use three separate 1D array variables than three dimensions in one variable. Again using your variables above:

julia> e[b .> a] .= 0
2-element view(::Array{Int64,1}, [1, 2]) with eltype Int64:
 0
 0

julia> e
3-element Array{Int64,1}:
 0
 0
 4

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...