保留每列的 n 个最大值,并在 MATLAB 中将其余值设置为零,无需循环
Keep n largest values per column and set the rest to zero in MATLAB without a loop
我有一个未排序数字矩阵,我想保留每列的 n 个最大(不一定唯一)值并将其余值设置为零。
我想出了如何用循环来完成:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4]
k = 2
for n = 1:4
[y, ind] = sort(a(:,n), 'descend');
a(ind(k+1:end),n) = 0;
end
a
这给了我:
一个=
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
k=
2
一个=
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0
然而,当我试图消除循环时,我似乎无法获得正确的索引,因为:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4]
k = 2
[y, ind] = sort(a, 'descend');
b = ind(k+1:end,:)
a(b) = 0
这给了我这个:(这不是我想做的)
一个=
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
k=
2
b =
4 3 3 1
1 2 2 4
一个=
0 8 12 5
0 2 6 18
0 3 9 7
0 9 12 4
我索引错了吗?我必须使用循环吗?
我参考了这个问题来开始,但这并不是我想要做的:How to find n largest elements in an array and make the other elements zero in matlab?
你非常接近。 sort
函数中的 ind
为您提供每列的行位置,其中特定值将出现在排序输出中。如果您想正确索引矩阵并消除条目,则需要做一些额外的工作。您知道对于 I
的每一列,这告诉您我们需要从该特定列中删除这些条目。因此,我要做的是使用 I
的每一列作为我们需要消除的行来生成列主要线性索引。
尝试这样做:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4];
k = 2;
[y, ind] = sort(a, 'descend');
%// Change here
b = sub2ind(size(a), ind(k+1:end,:), repmat(1:size(a,2), size(a,1)-k, 1));
a(b) = 0;
我们使用 sub2ind
来帮助我们生成列主索引,其中行由第 k
元素之后的 ind
中的值表示,我们需要的列是该矩阵中的每一列。在排序后截断 k
值后,还剩下 size(a,1)-k
行,因此我们生成的列值从 1 到与 a
中的列一样多剩余的行数。
我们得到这个输出:
>> a
a =
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0
这是一个使用 bsxfun
-
%// Get descending sorting indices per column
[~, ind] = sort(a,1, 'descend')
%// Get linear indices that are to be set to zeros and set those in a to 0s
rem_ind = bsxfun(@plus,ind(n+1:end,:),[0:size(a,2)-1]*size(a,1))
a(rem_ind) = 0
样本运行-
a =
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
n =
2
ind =
3 4 1 2
2 1 4 3
4 3 3 1
1 2 2 4
rem_ind =
4 7 11 13
1 6 10 16
a =
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0
我有一个未排序数字矩阵,我想保留每列的 n 个最大(不一定唯一)值并将其余值设置为零。
我想出了如何用循环来完成:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4]
k = 2
for n = 1:4
[y, ind] = sort(a(:,n), 'descend');
a(ind(k+1:end),n) = 0;
end
a
这给了我: 一个=
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
k=
2
一个=
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0
然而,当我试图消除循环时,我似乎无法获得正确的索引,因为:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4]
k = 2
[y, ind] = sort(a, 'descend');
b = ind(k+1:end,:)
a(b) = 0
这给了我这个:(这不是我想做的) 一个=
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
k=
2
b =
4 3 3 1
1 2 2 4
一个=
0 8 12 5
0 2 6 18
0 3 9 7
0 9 12 4
我索引错了吗?我必须使用循环吗?
我参考了这个问题来开始,但这并不是我想要做的:How to find n largest elements in an array and make the other elements zero in matlab?
你非常接近。 sort
函数中的 ind
为您提供每列的行位置,其中特定值将出现在排序输出中。如果您想正确索引矩阵并消除条目,则需要做一些额外的工作。您知道对于 I
的每一列,这告诉您我们需要从该特定列中删除这些条目。因此,我要做的是使用 I
的每一列作为我们需要消除的行来生成列主要线性索引。
尝试这样做:
a = [4 8 12 5; 9 2 6 18; 11 3 9 7; 8 9 12 4];
k = 2;
[y, ind] = sort(a, 'descend');
%// Change here
b = sub2ind(size(a), ind(k+1:end,:), repmat(1:size(a,2), size(a,1)-k, 1));
a(b) = 0;
我们使用 sub2ind
来帮助我们生成列主索引,其中行由第 k
元素之后的 ind
中的值表示,我们需要的列是该矩阵中的每一列。在排序后截断 k
值后,还剩下 size(a,1)-k
行,因此我们生成的列值从 1 到与 a
中的列一样多剩余的行数。
我们得到这个输出:
>> a
a =
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0
这是一个使用 bsxfun
-
%// Get descending sorting indices per column
[~, ind] = sort(a,1, 'descend')
%// Get linear indices that are to be set to zeros and set those in a to 0s
rem_ind = bsxfun(@plus,ind(n+1:end,:),[0:size(a,2)-1]*size(a,1))
a(rem_ind) = 0
样本运行-
a =
4 8 12 5
9 2 6 18
11 3 9 7
8 9 12 4
n =
2
ind =
3 4 1 2
2 1 4 3
4 3 3 1
1 2 2 4
rem_ind =
4 7 11 13
1 6 10 16
a =
0 8 12 0
9 0 0 18
11 0 0 7
0 9 12 0