How to extract elements along one dimension in an n-d array based on an arbitrary criterion.

47 visualizzazioni (ultimi 30 giorni)
As an example, let's say that I had some 3-D array.
A = 2*rand(100,100,10) -1; % random 100x100x10 array [-1, 1]
And I want some 100x100 array extracted from A at the page determined by some arbitrary criterion. The first example would be min:
B = min(A,[],3);
which actually works; it returns a 100 x 100 array with the minimum values along A. However, what if I wanted to extract the points based off of say the absolute value, but wanted the signed versions of these:
[B, I] = min(abs(A),[],3);
does not work, as it returns the abs(A) components, not the signed version. I assume what I really want is to use the index I. However, I do not understand how to then do this efficiently, e.g. something like
B = A(I);
or
B = A(:,:,I);
Neither of these methods work; the first treats the index I across all of A, and will only pick one of the first 10 elements (incorrectly). The second simply fails because I is a 100 x 100 matrix.
There has to be an elegant way of performing this type of operation, in this example extracting the matrix that meets the chosen criterion along the page direction. It would be useful for any type of sorting or selecting where an index along one dimension is returned, e.g. max, min, find, etc.
I am hoping to do this without any kind of reshaping, but I understand that might be necessary. Something like this operation must be being performed inside of min already, and I think the answer is going to be obvious once I see it.
The above MWE is just an stand in for the kind of index selection in an N-D matrix I might want.
Thanks for your help, Dan

Risposta accettata

Guillaume
Guillaume il 13 Dic 2016
One possible way, using ind2sub:
[~, page] = min(abs(A), [], 3);
[rows, columns] = ndgrid(size(A, 1), size(A, 2));
B = A(sub2ind(size(A), rows, columns, page));
  1 Commento
D. Plotnick
D. Plotnick il 8 Feb 2017
Excellent idea (and exactly what I needed) with one minor correction and one addition. Your second line needs to read:
[rows, columns] = ndgrid(1:size(A, 1), 1:size(A, 2));
if
[M,N,O] = size(A)
then rows, columns, and pages need to be three matrices of size [M,N] in order for sub2ind to work.
Also, to get it into the format I wanted, also add the line
B = reshape(B, [M,N])
will return you an array with the expected size and organizational scheme.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Matrices and Arrays in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by