从矩阵中提取每第 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 index 在 A
中的列生成所需的输出。
一行,因为我们可以:
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 在评论中正确指出的那样,您可以通过将 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
进行运算。
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=4
和 N=8
,所以 I
是:
1 5
2 6
3 7
然后你只用索引得到你的矩阵:
X = A(:,I);
我需要从我的矩阵中提取每第 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 index 在 A
中的列生成所需的输出。
一行,因为我们可以:
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 在评论中正确指出的那样,您可以通过将 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
进行运算。
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=4
和 N=8
,所以 I
是:
1 5
2 6
3 7
然后你只用索引得到你的矩阵:
X = A(:,I);