Просмотры / операции с массивом с гибким количеством измерений

#julia

#julia

Вопрос:

Есть ли элегантный и короткий способ написать функции, которые написаны ниже, за один раз, в одном определении? Чтобы функция работала с массивом с гибким числом измерений, добавляя : s по мере необходимости? В идеале, чтобы он также имел N размеры.

 ind = 1:5

view_something(A::AbstractArray{T,1}, ind) where {T} = view(A, ind)
view_something(A::AbstractArray{T,2}, ind) where {T} = view(A, :, ind)
view_something(A::AbstractArray{T,3}, ind) where {T} = view(A, :, :, ind)

view_something(rand(10,10,10), ind)
view_something(rand(10,10), ind)
view_something(rand(10), ind)
 

Я заметил, что можно вызвать Colon operator и собрать аргументы функций в таком векторе [Colon(),Colon(),...] , это правильный путь или есть другие способы, которые являются предпочтительными?

Комментарии:

1. Существует пакет, предоставляющий оператор ( .. , IIRC) именно для этого, который работает как ... в массивах Numpy. Но я забыл, как это называется … 🙁

2. @phipsgabler EllipsisNotation.jl

Ответ №1:

eachslice(A, dims = d) дает вам итератор, в котором все остальные измерения :

selectdim(A, d, ind) дает вам индивидуальный индекс.

Из подсказки справки: ?selectdim :

   selectdim(A, d::Integer, i)

  Return a view of all the data of A where the index for dimension d equals i.

  Equivalent to view(A,:,:,...,i,:,:,...) where i is in position d.

  See also: eachslice.
 

и ?eachslice :

   eachslice(A::AbstractArray; dims)

  Create a generator that iterates over dimensions dims of A, returning views that select all the data from the other
  dimensions in A.

  Only a single dimension in dims is currently supported. Equivalent to (view(A,:,:,...,i,:,: ...)) for i in axes(A,
  dims)), where i is in position dims.
 

Комментарии:

1. Идеальный. Именно то, что я хотел и не мог найти. Спасибо.

2. Добро пожаловать!

3. Разве вы не пропустили параметр d в selectdim(A,ind) ?

4. Ха, да. Спасибо!

Ответ №2:

Как насчет следующего:

 ind = 1:5
view_something(A::AbstractArray{T,N}, ind) where {T, N} = 
      view(A, [Colon() for i in 1:(N-1)]..., ind)

view_something(rand(10,10,10), ind)
view_something(rand(10,10), ind)
view_something(rand(10), ind)
 

Ответ №3:

EllipsisNotation.jl был написан именно для этой цели и позволяет вам делать это удобно, аналогично тому, как ... работает оператор в Numpy:

 view_something(A::AbstractArray{T}, ind) where {T} = view(A, .., ind)