从矩阵中提取每第 n 列

Extracting every n-th column from matrix

我需要从我的矩阵中提取每第 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 列和第 n 行,但我不知道如何使用它来获得我需要的东西。

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

然后我们可以使用最后一个作为 logical indexA 中的列生成所需的输出。

一行,因为我们可以:

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

如果您希望每四列 "save",则语法为:

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

正如 Wolfie 在评论中正确指出的那样,您可以通过将 toRemoveA(:,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进行运算。

This is a slightly more general solution, for cases when a clear periodicity doesn't exist within the IDs of the columns to be excluded; added for completeness.


假设您有矩阵 A,列 N,并且您想要排除 ID 在向量 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

构建列索引向量很容易,可以通过多种方式实现。例如,如果您想跳过每第 n 列并且矩阵中有 N 列:

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

请注意,+ 沿所有维度运行;在旧版本的 Matlab 中,您应该使用 bsxfun 代替。

在你的例子中,n=4N=8,所以 I 是:

1    5
2    6
3    7

然后你只用索引得到你的矩阵:

X = A(:,I);