Reputation: 838
I am trying to figure out (in Julia) how to extract a portion of an array along a specified dimension, when the dimension itself is a variable. If the dimension is known it is straightforward to extract a portion of an array. For example, I can extract a portion along the 3rd dimension by doing something like this:
A = rand(27,33,11)
A_portion = A[:,:,3:7]
Is there a compact/efficient method for extracting a portion of an array along a variable dimension? For example, something that looks like this?
A = rand(27,33,11)
dim = 3 ## dimension along which to grab a portion of the array
first_element = 3 ## first element over specified dimension
last_element = 7 ## last element over specified dimension
A_portion = MyFunction(A,dim,first_sample,last_sample)
One possibility is to write a set of if-statements for every possible combination of array dimension (up to some maximum number of dimensions) and dimension along which to extract the portion. For example, something like this:
MyFunction(A::Array,dim::Int,first_element::Int,last_element::Int)
if ndims(A)==1 && dim==1
return A[first_element:last_element]
elseif ndims(A)==2 && dim==1
return A[first_element:last_element,:]
elseif ndims(A)==2 && dim==2
return A[:,first_element:last_element]
elseif ndims(A)==3 && dim==1
...
...
...
Clearly this becomes quite messy in order to allow for arrays with large numbers of dimensions. Is there a more compact/efficient approach for doing this?
Upvotes: 5
Views: 2318
Reputation: 669
I will propose another solution because it turns out that selectdim
is not compatible for objects like HDF5 dataframes. Instead I will create an array of Colon
's, repeat the colons an appropriate number of times using repeat
, then unwrap them either side of the desired location using ...
.
arr = zeros(10,10,10,10,10); # example array
d = 1 # dimension to slice
i = 4 # index on d to slice
slice = arr[repeat([:],d-1)..., i, repeat(Any[:],ndims(arr)-d)...]
Upvotes: 0
Reputation: 61
Jeff Bezanson's post is correct, but the function slicedim
was renamed to selectdim
see julia github
julia> a = rand(2,2,2)
2×2×2 Array{Float64,3}:
[:, :, 1] =
0.835392 0.645282
0.398793 0.774604
[:, :, 2] =
0.00894267 0.191362
0.700798 0.897556
julia> selectdim(a, 1, 2)
2×2 view(::Array{Float64,3}, 2, :, :) with eltype Float64:
0.398793 0.700798
0.774604 0.897556
julia> selectdim(a, 3, 1)
2×2 view(::Array{Float64,3}, :, :, 1) with eltype Float64:
0.835392 0.645282
0.398793 0.774604
(not enough reputation to write comment)
Upvotes: 6
Reputation: 3207
The function slicedim
does this:
julia> a = rand(2,2,2)
2×2×2 Array{Float64,3}:
[:, :, 1] =
0.754584 0.133549
0.363346 0.731388
[:, :, 2] =
0.415001 0.907887
0.301889 0.763312
julia> slicedim(a, 1, 2)
2×2 Array{Float64,2}:
0.363346 0.301889
0.731388 0.763312
julia> slicedim(a, 3, 1)
2×2 Array{Float64,2}:
0.754584 0.133549
0.363346 0.731388
The second argument specifies the dimension number. In the first case, we selected index 2 in dimension 1. In the second case, we selected index 1 in dimension 3.
You can also hack together approaches to this using something like a[fill(:,2)...,1]
which "splats" two :
s into the argument list followed by a 1
.
Upvotes: 7