Towards an eachsliceX function

eachslice does the opposite of what I would like. For instance, if X is a 3D array, then eachslice(X,dims=1) gives an iterator over 2D matrices. Rather, I would like an iterator over all ‘column vectors’, like eachcol(). The following code does that for arrays with 3 or fewer dimensions. (It’s straightforward to instead get iterators over rows or ‘aisles’)

Now, my questions is: is there a simple generalisation of this? If so, I think we should make a PR. Suggestions are welcome.

function eachcol3D(A::AbstractArray)
  if 1 <= ndims(A) <= 2
    z = eachcol(A)           #(view(A,:,i) for i in axes(A,2))
  elseif ndims(A) == 3
    z = (view(A,:,i,j) for i in axes(A,2), j in axes(A,3))
  else
    error("this function works only on 1D-3D arrays")
  end
  return z
end
1 Like

what’s the “physical” significance of such a column? you can easily reshape it into something that works with eachcol:

julia> a = rand(3,3,3)

julia> yours = first((view(a,:,i,j) for i in axes(a,2), j in axes(a,3)));

julia> first(eachcol(reshape(a, size(a,1), :))) == yours
true

I should note reshape is non-allocating, comment:

reshape(a, size(a,1), :)

makes a matrix such that each column is as tall as your original first dimension.


You can also create the same iterator (like your z) with:

Iterators.partition(vec(a), size(a,1))

vec also doesn’t allocate, it just presents the underlying memory as a 1D vector

1 Like

There is #32310, with which what you ask for is eachslice(X, dims=(2,3)).

I find

https://github.com/bramtayl/JuliennedArrays.jl/

very useful for slicing.

3 Likes