Извлечение каждого n-го столбца из матрицы - PullRequest
0 голосов
/ 03 мая 2018

Мне нужно извлечь каждый n-й столбец из моей матрицы.

Например, у меня есть матрица:

A =
     1    23    34    53    67    45    67    45
    12    34    45    56    67    87    98    12
     1     2     3    45    56    76    87    56

И я хочу извлечь каждую группу из трех столбцов, то есть удалить каждый четвертый. Мои данные должны быть такими:

X =
     1    23    34    67    45    67
    12    34    45    67    87    98
     1     2     3    56    76    87

Так что я бы пропустил 4-й столбец, затем 8-й столбец и так далее. Я знаю, как извлечь каждый n-й столбец и строку, но я не мог понять, как использовать это, чтобы получить то, что мне нужно.

Ответы [ 4 ]

0 голосов
/ 03 мая 2018

Построить вектор индексов столбцов легко, вы можете сделать это несколькими способами. Например, если вы хотите пропустить каждый n-й столбец и в вашей матрице есть N столбцов:

I = (1:n-1).'+(0:n:N-1);

Обратите внимание, что + работает по всем измерениям; в старых версиях Matlab вы должны использовать bsxfun.

В вашем случае n=4 и N=8, поэтому I равно:

1    5
2    6
3    7

Тогда вы получите свою матрицу только с индексированием:

X = A(:,I);
0 голосов
/ 03 мая 2018

Если вы хотите «сохранить» каждый четвертый столбец, то синтаксис будет:

toKeep = 4:4:8;
A = rand(3,8) % Insert your matrix
B = A(:,toKeep);

т.е. Вы присваиваете эти значения новой матрице. В вашем случае вы хотите удалить их, поэтому вы можете просто назначить пустую матрицу тем местам, которая практически удаляет их.

toRemove = 4:4:8; %Every fourth column
A = rand(3,8) % Insert your matrix
A(:,toRemove) = [];

РЕДАКТИРОВАТЬ 1

Как правильно заметил Вольф в комментариях, вы можете немного улучшить это, написав toRemove вместе с A(:,toRemove) и используя ключевое слово end, чтобы у вас было:

A = rand(3,8) % Insert your matrix
A(:,4:4:end) = [];

В этом случае вам не нужно беспокоиться о размере матрицы.

РЕДАКТИРОВАТЬ 2:

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

toRemove = randperm(8,randi(5)); %Select up to 5 random columns to remove
A = rand(3,8) % Insert your matrix
A(:,toRemove) = [];

PS. Если вы хотите сохранить исходную матрицу, A вы можете сначала присвоить ее B=A;, а затем выполнить операцию с B.

0 голосов
/ 03 мая 2018

Это немного более общее решение для случаев, когда четкая периодичность не существует в идентификаторах столбцов, которые нужно исключить; добавлено для полноты.


Предположим, у вас есть матрица A со столбцами N, и вы хотите исключить столбцы, идентификаторы которых находятся в векторе E, вы можете использовать функцию setdiff, как показано ниже:

N = randi([30 50]);        % Generate data size
A = randi(N^2,N,N);        % Generate data
E = randperm(N,randi(10)); % Define column ids to exclude
X = A(:,setdiff(1:N,E));   % Create output

Применительно к вашему примеру это будет выглядеть так:

S = size(A,2);
X = A(:, setdiff(1:S,4:4:S) ); % No need for the intermediate variable E
0 голосов
/ 03 мая 2018
A = rand(3,8) % Insert your matrix
n = 4; % Index of column to skip
idx = 1:size(A,2) % create indexing array
B = A(:,mod(idx,n)~=0) % logically index
A =
    0.7094    0.6797    0.1190    0.3404    0.7513    0.6991    0.5472    0.2575
    0.7547    0.6551    0.4984    0.5853    0.2551    0.8909    0.1386    0.8407
    0.2760    0.1626    0.9597    0.2238    0.5060    0.9593    0.1493    0.2543
idx =
     1     2     3     4     5     6     7     8
B =
    0.7094    0.6797    0.1190    0.7513    0.6991    0.5472
    0.7547    0.6551    0.4984    0.2551    0.8909    0.1386
    0.2760    0.1626    0.9597    0.5060    0.9593    0.1493

Идея в том, что вы создаете индексный массив idx, а затем проверяете, где деление idx на желаемое n равно нулю. Всякий раз, когда это происходит, вы хотите пропустить этот столбец. Разбивка:

mod(idx,n) % 0 whenever idx is entirely divisible by n
mod(idx,n)==0 % finds where the zeros are
~(mod(idx,n)==0) % finds wherever the non-zeros are, i.e. the columns we want

тогда мы можем использовать последний как логический индекс для столбцов в A, генерируя желаемый результат.

Однострочник, потому что мы можем:

B = A(:,mod(1:size(A,2),n)~=0)
...