Extract multiple columns from a 3d matrix

I currently have an array A with sizes N xtx t. I want to create a two-dimensional N xt matrix of the form:

B = [ A[:,1,1] A[:,2,2],...,A[:,t,t]] 

Obviously, the two ways that I could do this are to write it in its entirety (impractical since t is large) and loops (potentially slow). Is there any way to do this without loops. I figured this would work if I did this:

 B = A[:,[1:end],[1:end]] 

but it just returned me the original matrix.

+4
source share
3 answers

Basically, you need to think about how to reorganize your matrix.

Of

 A = randn([5 3 3]); 

Look at

 A(:,:) 

Basically you need columns 1, 5, 9. Thinking about this, knowing t = 3, from the current column you want to increase by t + 1. The formula is basically:

 ((1:3)-1)*(3+1)+1 %(or (0:2)*(3+1) + 1) 

What is connected to A, you get your decision

 A(:,((1:3)-1)*(3+1)+1) 

In general format you can:

 A(:,((1:t)-1)*(t+1)+1) 

EDIT:

Amro basically just dishonored me. The idea remains the same, it becomes more readable thanks to end

Therefore use:

 A(:,1:t+1:end) 
+8
source

Here is my question on this:

 mask = repmat(logical(permute(eye(size(A,2)), [3 1 2])), size(A,1), 1); newA = reshape(A(mask), size(A,1), []); 

Just generate a mask, apply it and change the shape to the correct shape.

Edit:

Or even simpler:

 newA = A(:, logical(eye(size(A,2)))) 

or along the same lines

 newA = A(:, diag(true(size(A,2),1))); 

which is a little faster.

+3
source

MATLAB is pretty good with vectors and matrices, but when it comes to "general arrays", you often have to switch to "general methods". When you are accustomed to the ease with which you manipulate matrices / vectors, it will seem really awkward, backward and not very convenient at all (in fact, these are very justified reasons for this, but this is a discussion at another time :).

The version below goes through each page through arrayfun (which runs faster than a regular loop for large matrices) and calls diag on each page:

 % "flip" the array, so that 3rd dimension becomes the 1st (rows), and % the 1st dimension becomes the 3rd, so that each "page" is a regular % matrix. You want the diagonals of all these matrices. b = permute(a, [3 2 1]); % Now "loop" through the pages, and collect the matrix diagonal for each page c = arrayfun(@(ii)diag(b(:,:,ii)), 1:size(b,3), 'UniformOutput', false); % The above will output a cell-array, which you can cast back to % a numeric matrix through this operation: A = [c{:}]; 
+1
source

Source: https://habr.com/ru/post/1488301/


All Articles