MATLAB - переупорядочить матрицу путем вертикальной конкатенации подматриц

У меня возникли проблемы со следующей задачей: Предположим, что матрица 3x6:

A =

0.2787    0.2948    0.4635    0.8388    0.0627    0.0435
0.6917    0.1185    0.3660    0.1867    0.2383    0.7577
0.6179    0.7425    0.0448    0.4009    0.9377    0.4821

Я хотел бы разделить матрицу на блоки, например:

A =

0.2787    0.2948  |  0.4635    0.8388  |  0.0627    0.0435
0.6917    0.1185  |  0.3660    0.1867  |  0.2383    0.7577
0.6179    0.7425  |  0.0448    0.4009  |  0.9377    0.4821

и вертикально объединить эти блоки, чтобы получить конечный результат:

0.2787    0.2948 
0.6917    0.1185  
0.6179    0.7425  
0.4635    0.8388
0.3660    0.1867
0.0448    0.4009
0.0627    0.0435
0.2383    0.7577
0.9377    0.4821

Я думаю, что если я смогу получить помощь с этим, то я могу, возможно, сделать это для произвольных матриц А. Я могу решить выше проблема с использованием for-loop, но я ищу векторизованное решение.

Заранее спасибо! Н.

 kevlar181805 июн. 2012 г., 22:46
Уважатьreshape.
 Amro05 июн. 2012 г., 23:13
для тех, кто заинтересован, вот связанный вопрос:split long 2D matrix into the third dimension
 user143831005 июн. 2012 г., 22:47
Я думаю, что это займет больше, чем изменить. Я имею в виду изменение формы в сочетании с какой-то другой операцией ...
 kevlar181806 июн. 2012 г., 15:03
@ user1438310 Да, я знаю. Я упоминал инструмент, о котором вы могли не знать. Я бы не упомянул об этом, если бы вы включили что-то в то, что вы пробовали.

Ответы на вопрос(5)

Решение Вопроса

A = rand(3,6);
blkSz = 2;

C = mat2cell(A, size(A,1), blkSz*ones(1,size(A,2)/blkSz));
C = cat(1,C{:})

Это предполагает, чтоsize(A,2) делится равномерноblkSz

 05 июн. 2012 г., 23:16
ТАК не обновлялся до тех пор, пока я не опубликовал свой ответ. :)
 05 июн. 2012 г., 23:41
@ChrisA .: спасибо, теперь я должен вернуть услугу :)
 user143831005 июн. 2012 г., 23:07
Спасибо за ответ, мне потребуется время, чтобы применить ваше решение к моему коду, но я свяжусь с вами ..
 05 июн. 2012 г., 23:24
@ChrisA .: не могу сказать, сколько раз это случалось и со мной ..
 05 июн. 2012 г., 23:26
@Amro Я обязан повысить твои голоса, и я не расстраиваюсь из-за того, что ты меня собрал.

without cell2mat, (только сreshapeс иpermute) и, следовательно, намного быстрее!

Вам необходимо использовать «3-е измерение». Это похоже на то, что описано в разбить длинную 2D матрицу на третье измерение.

Вот решение для вышеуказанной матрицы:

A1 = reshape(A, 3, 2, []);  % 3rd dimension is numel(A)/2/3
A2 = permute(A1, [2 1 3]);  % transpose 1st and 2nd dimension
Ans= reshape(A2, 2, [])' ;  % note the transpose

Для матрицы такого размера разница во времени выполнения незначительна. Однако для большой матрицы разница больше чем на порядок:

A=rand(3, 2*10000);

%% good method

tic
A1 = reshape(A, 3, 2, []); %3rd dimension is numel(A)/2/3
A2 = permute(A1, [2 1 3]);
A3 = reshape(A2, 2, [])' ; %note the transpose'
toc

%% mat2cell method

tic
blkSz = 2;
C = mat2cell(A, size(A,1), blkSz*ones(1,size(A,2)/blkSz));
B3 = cat(1,C{:});
toc

%% make sure the answer is the same:
assert(max(A3(:)-B3(:))==0)

выход:

>> Elapsed time is 0.001202 seconds.
>> Elapsed time is 0.043115 seconds.

Как насчет этого:

width = 2; 
m = length(A(:))/width;
fn = @(i) reshape(A(:, i:width:end), m, 1);
B = cell2mat(arrayfun(fn, 1:width, 'UniformOutput', false));

Просто укажите, сколько столбцов вы хотите за один раз вwidth переменная.

Это работает там, где ваша матрицаA и что вы хотитеD

C = mat2cell(A,[3],[2 2 2])
D = cat(1,C{:})
 user143831006 июн. 2012 г., 12:23
Большое спасибо, это прекрасно работает и экономит мое время.

При вертикальной конкатенации матричная ширина, делимая на 3, предполагает:

B = [ A(:,1:(size(A,2)/3)); A(:,size(A,2)/3+1:size(A,2)/3*2); A(:,size(A,2)/3*2+1:end) ];

Ваш ответ на вопрос