首页 > 解决方案 > 在空间中找到靠近另一个数组的数组元素?

问题描述

我基本上想使用该功能ismember,但是对于一个范围。例如,我想知道 中的每个元素的距离array1内的数据点。narray2array2

我有以下内容:

array1 = [1,2,3,4,5]
array2 = [2,2,3,10,20,40,50]

我想知道什么值远离array2<= 2array1

indices(1,:) (where array1(1) = 1)     = [1 1 1 0 0 0 0]
indices(2,:) (where array1(2) = 2)     = [1 1 1 0 0 0 0]
indices(3,:) (where array1(3) = 3)     = [1 1 1 0 0 0 0]
indices(4,:) (where array1(4) = 4)     = [1 1 1 0 0 0 0]
indices(5,:) (where array1(5) = 5)     = [0 0 1 0 0 0 0]

缺点:

myarray1是 496736 个元素,myarray2是 9268 个元素,所以我宁愿不使用循环。

标签: arraysmatlabmatrixlogical-operators

解决方案


循环是一个有效的选项。将数组初始化output为 的大小array1 X array2,然后循环遍历所有元素并从中array1减去array2,然后检查绝对值是否小于或等于2

array1 = [1,2,3,4,5];
array2 = [2,2,3,10,20,40,50];

output = zeros(numel(array1), numel(array2),'logical');

for ii = 1:numel(array1)
   output(ii,:) = abs(array1(ii)-array2)<=2;
end
output =

     1     1     1     0     0     0     0
     1     1     1     0     0     0     0
     1     1     1     0     0     0     0
     1     1     1     0     0     0     0
     0     0     1     0     0     0     0

即循环不是问题。

感谢 Rahnema1 的建议,您可以output直接初始化为逻辑矩阵:

output = zeros(numel(array1),numel(array2),'logical');

其大小仅为 4.3GB。


关于时间:Hans 的代码在几秒钟内运行array1 = 5*rand(496736,1); array2 = 25*rand(9286,1);,循环解决方案需要大约 15 倍的时间。两种解决方案彼此相等。obcahrdon 的ismembertol解决方案在我的机器上介于两者之间。


关于 RAM 使用情况:

  • 根据 Hans 的回答,隐式扩展以及我在我的工作中建议的循环在扩展问题大小(496736*9286)上仅使用 4.3GB RAM
  • pdist2bsxfun另一方面,根据 Luis 的回答和Hans 的回答,尝试创建一个 34GB 的中间双矩阵(它甚至不适合我的 RAM,所以我无法比较时间)。
  • obchardon 的ismembertol解决方案输出了一种不同形式的解决方案,大约需要 5.04GB(高度依赖于找到的匹配数量,越多,这个数字就越大)。

一般来说,这使我得出结论,隐式扩展应该是您的选择,但如果您有 R2016a 或更早版本,ismembertol或者循环是要走的路。


推荐阅读