How to "localize" slicing an array?

How can I “localize” slicing on dimension relative to “available” indices? In the example below, I would need L[:, j] to mean “get all elements along dimension 1 relative to elements present in skipzeros”. How can I do that?

L = rand(10, 10)
idx0 = rand(0:1, size(L))
L .= L .* idx0

skipzeros = filter(x -> x ∉ findall(L .== 0), CartesianIndices((1:10, 1:10))

for idx in skipzeros
    i, j = Tuple(idx)
    t1 = L[:, j] .+ 100
end

Is the following what you want? (taking the liberty to simplify the code a bit)

L = rand(10, 10) .* rand.(Bool)

skipzeros = findall(!=(0), L)

for idx in skipzeros
    same_2nd = getindex.(skipzeros, 2) .== idx[2]
    t1 = L[skipzeros[same_2nd]] .+ 100
end

This makes a vector skipzeros[same_2nd] which contains all the Cartesian indices that satisfy the condition. Then instead of slicing with [:, j] you can use this list of Cartesian indices to extract the corresponding values from L.

1 Like

This does it, thank you. Could there be a more streamlined way?

It depends what you really want to do. The given example finds the nonzero values in the same column for each nonzero value in L, and adds 100. So if column 3 has 5 nonzero values, it will calculate 5 times the same vector v .+ 100 (where v is the list of nonzero values in column 3). A simpler way to do this is

L = rand(10, 10) .* rand.(Bool)
cols_nozero = filter.(!iszero, eachcol(L))
[v .+ 100 for v in cols_nozero for _ in v]
1 Like