【问题标题】:How to get elements larger than x in a given range?如何在给定范围内获取大于 x 的元素?
【发布时间】:2014-12-31 22:01:55
【问题描述】:

给定一个矩阵A,如何在特定范围内获得大于x 的元素(及其索引)?

例如

A = [1:5; 2:6; 3:7; 4:8; 5:9]

A =

     1     2     3     4     5
     2     3     4     5     6
     3     4     5     6     7
     4     5     6     7     8
     5     6     7     8     9

例如,我希望所有大于 5 的元素都出现在A(2:4,3:5) 范围内。我应该得到:

元素:

6 , 6 , 7 , 6 , 7 , 8

指数:

14, 18, 19, 22, 23, 24

A(A>5) 会给我所有大于 5 的条目。

A(2:4,3:5) 将给出2:4,3:5 范围内的所有元素。

我想要两者的某种组合。是否有可能或唯一的方法是将所需的范围放在另一个数组B 中,然后才执行B(B>5)?显然这里有两个问题:我会丢失原始索引,而且速度会更慢。我在大量矩阵上执行此操作。

【问题讨论】:

标签: arrays matlab matrix


【解决方案1】:

代码。我试图避免矩阵乘法,所以这看起来有点奇怪:

A = [1:5; 2:6; 3:7; 4:8; 5:9];

[r,c] = meshgrid(2:4,3:5);
n     = sub2ind(size(A), r(:), c(:));

indices = sort(n(A(n) > 5)); %'skip sorting if not needed'
values  = A(indices);

解释。 代码将下标的笛卡尔积转换为A 矩阵中的线性索引。然后它选择符合条件的索引,然后选择值。

但是,它很慢。

优化。按照LuisMendo 的建议,可以通过将基于sub2ind 的线性索引计算替换为手工制作的线性索引计算来加快代码速度:

A = [1:5; 2:6; 3:7; 4:8; 5:9];

%'For column-first, 1-based-index array memory   '
%'layout, as in MATLAB/FORTRAN, the linear index '
%'formula is:                                    '
%'L = R + (C-1)*NR                               '
n = bsxfun(@plus, (2:4), (transpose(3:5) - 1)*size(A,1)); 

indices = n(A(n) > 5);
values  = A(indices);

【讨论】:

  • 哇!很快!比使用临时矩阵快 2.5 倍!
  • 并且不需要排序。
  • 可能更快:n = bsxfun(@plus, (2:4), ((3:5).'-1)*size(A,1)); 而不是 meshgridsub2ind
  • @LuisMendo 用手工制作的线性索引计算替换 meshgridsubs2ind 这两个昂贵的调用确实是个好主意。
  • @AlaaM。 Here'smeshgrid/ndgrid + sub2indbsxfun 的基准比较,以解决相关问题,并且很少了解使用 bsxfun 获得更好性能的可能原因。
【解决方案2】:

如果您只需要值(而不是索引),可以使用find 的第三个输出和矩阵乘法来完成。不过,我不知道它是否会比使用临时数组更快:

[~, ~, values] = find((A(2:4,3:5)>5).*A(2:4,3:5));

假设你需要线性索引和值,那么如果阈值为正你可以定义一个掩码。如果掩码可以定义一次并用于所有矩阵(也就是说,如果所有矩阵的所需范围相同),这可能是一个好主意:

mask = false(size(A));
mask(2:4,3:5) = true;
indices = find(A.*mask>5);
values = A(indices);

【讨论】:

  • 索引实际上更重要。不过我会调查答案。谢谢
  • 如何让mask 稀疏?如果有小测试“窗口”,它可能有助于解决内存问题。
  • @CST-Link 内存效率的好主意!至于速度我不太确定
【解决方案3】:

有点笨拙,但是:

R = 2:4;
C = 3:5;
I = reshape(find(A),size(A))

indicies = nonzeros(I(R,C).*(A(R,C)>5))
values = A(indicies)

【讨论】:

  • 这会给出索引吗?
猜你喜欢
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2011-04-01
  • 2022-08-14
  • 1970-01-01
相关资源
最近更新 更多