Вопрос по matrix, matlab – MATLAB - переупорядочить матрицу путем вертикальной конкатенации подматриц

4

У меня возникли проблемы со следующей задачей: Предположим, что матрица 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, но я ищу векторизованное решение.

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

Я думаю, что это займет больше, чем изменить. Я имею в виду изменение формы в сочетании с какой-то другой операцией ... user1438310
Уважатьreshape. kevlar1818
@ user1438310 Да, я знаю. Я упоминал инструмент, о котором вы могли не знать. Я бы не упомянул об этом, если бы вы включили что-то в то, что вы пробовали. kevlar1818
для тех, кто заинтересован, вот связанный вопрос:split long 2D matrix into the third dimension Amro

Ваш Ответ

5   ответов
3

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

@ChrisA .: спасибо, теперь я должен вернуть услугу :)
@ChrisA .: не могу сказать, сколько раз это случалось и со мной ..
@Amro Я обязан повысить твои голоса, и я не расстраиваюсь из-за того, что ты меня собрал.
Спасибо за ответ, мне потребуется время, чтобы применить ваше решение к моему коду, но я свяжусь с вами .. user1438310
ТАК не обновлялся до тех пор, пока я не опубликовал свой ответ. :)
1

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

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

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

2

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.
3

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

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

При вертикальной конкатенации матричная ширина, делимая на 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) ];

Похожие вопросы