You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

求Matlab中快速查找数组A元素在唯一向量b中对应索引的方法

快速查找数组元素在唯一向量中的索引

嘿,针对你这个在大数组里快速查找唯一值索引的需求,我给你推荐几个高效的MATLAB方案,绝对能解决速度慢的问题:

方案1:用ismember直接获取索引(最推荐,一步到位)

MATLAB内置的ismember函数专门做这种成员匹配,而且底层是高度优化的,完全不需要自己写循环。因为你的b是唯一向量,刚好完美适配这个函数的索引输出:

[~, B] = ismember(A, b);

这里第一个返回值~我们直接忽略(它是一个和A同尺寸的逻辑矩阵,标记A的元素是否存在于b中),第二个返回值B就是你要的结果——A中每个元素在b对应的唯一索引。

这个方法的时间复杂度是O(M log N)(M是A的总元素数,N是b的长度),对比你之前嵌套循环的O(M*N),速度会提升几个数量级,而且完全不会有内存溢出的问题。用你给出的数据规模测试的话,应该能在0.1秒以内完成,比原来的5.5秒快几十倍。

方案2:排序+二分查找(适合数值型整数,速度再升级)

如果你的b还没排序,可以先对b排序,再用二分查找进一步提速:

% 先对b排序,同时记录原索引的映射关系
[sorted_b, idx_map] = sort(b);
% 用ismember在有序数组中做二分查找,获取位置
[~, pos] = ismember(A, sorted_b);
% 把位置映射回原b的索引
B = idx_map(pos);

因为ismember在面对有序数组时会自动使用二分查找,比无序数组的查找速度更快。如果你的元素都是整数,还可以用histcounts做离散化查找,速度会更极致:

[sorted_b, idx_map] = sort(b);
% 生成每个元素的边界,确保每个b元素对应唯一区间
edges = [-inf; (sorted_b(1:end-1)+sorted_b(2:end))/2; inf];
% 用histcounts找到A元素所在的区间位置
[pos, ~] = histcounts(A, edges);
% 映射回原索引
B = idx_map(pos);

为什么你之前的方法效率低?

我来帮你分析下之前几个方案慢的原因:

  • 嵌套循环:每次find(A(i,j)==b,1)都要遍历整个b数组,总操作次数是rows*columns*length(b)——按你的数据规模就是1e445e5=2e10次,完全是暴力遍历,速度必然慢。
  • 遍历b的循环B(A==b(idx))=idx每次都要对整个A做逻辑比较,生成大尺寸的逻辑矩阵,不仅内存开销大,循环次数更是达到5e5次,比嵌套循环的4e4次多了一个数量级,所以反而更慢。
  • bsxfun方案bsxfun(@eq,A(:,i),b)会生成一个rows×length(b)的巨大矩阵,按你的数据就是1e4*5e5=5e9个元素,直接超出内存限制,完全不可行。

内容的提问来源于stack exchange,提问作者Johannes

火山引擎 最新活动