#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)