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

조회 수: 60 (최근 30일)
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

채택된 답변

Guillaume
Guillaume 2016년 12월 13일
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
D. Plotnick
D. Plotnick 2017년 2월 8일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by