我试图在向量中找到与另一个向量对应的元素索引,最好不使用循环.例如,我的输入可能是:
DJiSet = [5 7 8];                   % elements of which I need the indices
JiSet = [3 4 5 6 7 8 9 11 12 20];   % vector to search
这里的输出是:
[3 5 6]
到目前为止,我提出的最快的是:
Output = find(ismember(JiSet,DJiSet));
但是我觉得这可以更快地完成,特别是因为我认为find命令相当慢.
注意事项:
DJiSet保证所有值都存在于中JiSetJiSet 始终按升序排序,无需重复输入DJiSet不保证连续找到矢量JiSetDiv*_*kar 10
方法#1
您可以find通过反转内部DJiSet和JiSet内部的位置来避免ismember,然后使用第二个输出来为我们提供匹配的索引 -
[~,out] = ismember(DJiSet,JiSet)
方法#2
可以尝试满足问题中设定的特定条件的Loopy方法,但不确定这是否会更有效 -
intv_idx = zeros(1,numel(DJiSet));
intv_idx(1) = find(JiSet==DJiSet(1),1);
start = intv_idx(1)+1;
for k = 2:numel(DJiSet)
    idx = find(JiSet(start:end)==DJiSet(k),1);
    start = idx+start;
    intv_idx(k) = idx;
end
out = cumsum(intv_idx);
迪瓦卡的答案是要走的路.但是如果你想手动更多:
[~, Output] = max(bsxfun(@eq, DJiSet(:).', JiSet(:)), [], 1);
如果有多个,则查找第一次出现.
如果值DJiSet是不能保证存在于JiSet,你可以使用一个小的修改:
[val, Output] = max(bsxfun(@eq, DJiSet(:).', JiSet(:))); %'
Output(~val) = 0; %// 0 indicates "not found"
对于小型数据集,似乎我的原始方法比ismemberDivakar提出的解决方案和intersectqmeeeeeee提出的解决方案都快,但所有三个都被Luis Mendo的解决方案打败了bsxfun.请参阅下面的代码,每种方法的次数:
function somescript()
IsmemberTime = timeit(@membersol)
IntersectTime = timeit(@intersectsol)
FindTime = timeit(@naivesol)
BsxTime = timeit(@bsxfunsol)
    function membersol()
        rng(1)
        set = randi(30,[1000 15]);             % generate 1000 vectors of length 15, containing random integers
        for i=1:1000
            [~,out] = ismember(set(i,1:5),set(i,6:end));      % first 5 random integers are the values to be found in the remainder of the vector
        end
    end
    function intersectsol()
        rng(1)
        set = randi(30,[1000 15]);
        for i=1:1000
            [~,~,Output] = intersect(set(i,1:5),set(i,6:end));
        end
    end
    function naivesol()
        rng(1)
        set = randi(30,[1000 15]);
        for i=1:1000
            Output = find(ismember(set(i,6:end),set(i,1:5)));
        end
    end
    function bsxfunsol()
        rng(1)
        set = randi(30,[1000 15]);
        for i=1:1000
            [~, Output] = max(bsxfun(@eq, set(i,1:5).', set(i,6:end)), [], 1);
        end
    end
end
在我的机器上(运行R2014b)返回以下时间:
IsmemberTime =
    0.1101
IntersectTime =
    0.2008
FindTime =
    0.0698
BsxTime =
    0.0218
这表明,对于小数据集至少,使用find和ismember基于矢量的反转顺序实际上比ismember单独使用更快.由于生成set用于测试的数据集的所有方法也有一些固定的开销,因此差异似乎相当大.可以在下面的评论中找到更全面的测试.
| 归档时间: | 
 | 
| 查看次数: | 534 次 | 
| 最近记录: |