Let's say I have a 3D array A, and I want to remove a slice:
A(i,:,:) = [];
But what if I don't know the dimension of the array beforehand? Just doing
A(i,:) = [];
Is valid, but reshapes the array into a 2D matrix.
I was thinking something like:
A(i,indices{:}) = [];
but I don't think you can put a colon operator in a cell.

 Réponse acceptée

Stephen23
Stephen23 le 12 Juin 2017
Modifié(e) : Stephen23 le 12 Juin 2017
If you do not know the size of the array before hand then you can call subsasgn directly. The function subsasgn is the actual function that MATLAB calls whenever you assign to an array using the indexing convenience operators () or {}, e.g. X(1) = 2, in just the same way that 1+2 is just a convenience operator for plus(1,2). We can also call subasgn directly, just like we could call plus if we so wished.
Here is a simple example of removing one row of A without hard-coding how many dimensions it has:
>> A = rand(5,4,3,2);
>> S.subs = repmat({':'},1,ndims(A));
>> S.subs{1} = 3; % the third row
>> S.type = '()';
>> B = subsasgn(A,S,[]);
>> size(B)
ans =
4 4 3 2

4 commentaires

Neat, I hadn't heard of this function. I should have just tried
colons = repmat({':'},1,ndims(A)-1);
A(idx,colons{:}) = [];
My guess about not being able to pass a comma separated list of colons to the indexing expression was clearly wrong.
Just for fun, I was trying to use subsref() to try and do the whole thing in one line:
subsref(repmat({':'},1,ndims(A)-1),struct('type','{}','subs',{{':'}}))
But for some reason
S.type = '{}';
S.subs = {':'};
subsref(colons,S)
Only outputs a single colon. Am I missing something?
It is not clear what you want to get from subsref, but this is a one-line equivalent of the code I gave in my answer:
>> A = rand(5,4,3,2);
>> B = subsasgn(A,struct('type','()','subs',{[{3},repmat({':'},1,ndims(A)-1)]}),[]);
>> size(B)
ans =
4 4 3 2
It looks like this has changed in more recent updates: I had been using this technique, but it failed when using it on a gpuArray. The included code below now works for gpuArrays and normal arrays:
A = gpuArray.rand(5,4,3,2);
v = repmat({':'},ndims(A),1);
v{1} = 3; % Do the third row
B = A;
B(v{:}) = []; % Note, you can replace this with a numeric to substitite instead of delete
size(B)
Stephen23
Stephen23 le 26 Mar 2020
Modifié(e) : Stephen23 le 26 Mar 2020
@Daniel Plotnick: you should put that as an Answer, so other users could vote for it.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by