【问题标题】:Intersection of multiple arrays without for loop in MATLABMATLAB中没有for循环的多个数组的交集
【发布时间】:2016-06-19 22:08:46
【问题描述】:

一直有人告诉我,在 MATLAB 中几乎所有的 for 循环都可以省略,而且它们通常会减慢处理速度。那么这里有没有办法做到这一点?:

我有一个单元阵列 (tsCell)。 tsCell 存储不同长度的时间数组。我想为所有时间数组(InterSection)找到一个相交的时间数组:

InterSection = tsCell{1}.time
for i = 2:length{tsCell};
    InterSection = intersect(InterSection,tsCell{i}.time);
end

【问题讨论】:

    标签: arrays matlab cell vectorization intersection


    【解决方案1】:

    这是使用uniqueaccumarray 的矢量化方法,假设输入元胞数组的每个元胞内没有重复项 -

    [~,~,idx] = unique([tsCell_time{:}],'stable')
    out = tsCell_time{1}(accumarray(idx,1) == length(tsCell_time))
    

    示例运行 -

    >> tsCell_time = {[1 6 4 5],[4 7 1],[1 4 3],[4 3 1 7]};
    
    >> InterSection = tsCell_time{1};
    for i = 2:length(tsCell_time)
        InterSection = intersect(InterSection,tsCell_time{i});
    end
    >> InterSection
    InterSection =
         1     4
    
    >> [~,~,idx] = unique([tsCell_time{:}],'stable');
    out = tsCell_time{1}(accumarray(idx,1) == length(tsCell_time));
    >> out
    out =
         1     4
    

    【讨论】:

    • @Jonas 如果您碰巧进行基准测试,您能否报告一下您最终使用实际数据可能获得的运行时改进?我很想知道这些数字。谢谢!
    • 我运行了一个 tsCell_time 的小样本,其中包含三个不同的时间数组(每个数组的条目长度约为 20000)。您改进的解决方案的运行时间为 0.017398 秒,而“原始”解决方案的运行时间为 0.019724。
    • 只需使用类似的集合再次运行它。这次是 0.017 对 0.021
    • @Jonas 嗯,我期待使用矢量化解决方案获得更好的数字。感谢您获得这些!
    • @Jonas:只有三个数组,循环进行了三次迭代,这是您可以忽略的开销。您必须摆脱循环进行多次迭代。
    【解决方案2】:

    这是另一种方式。这也假设每个原始向量中没有重复项。

    tsCell_time = {[1 6 4 5] [4 7 1] [1 4 3] [4 3 1 7]}; %// example data (from Divakar)
    t = [tsCell_time{:}]; %// concat into a single vector
    u = unique(t); %// get unique elements
    ind = sum(bsxfun(@eq, t(:), u), 1)==numel(tsCell_time); %// indices of unique elements
        %// that appear maximum number of times
    result = u(ind); %// output those elements
    

    【讨论】:

    • 我认为您的解决方案会更快,因为您省略了 accummary - 我会尝试在某个时候查看经过的时间 :)
    • @Jonas 您也可以尝试使用histc(idx,1:max(idx) 而不是accumarray(idx,1)
    • 有趣的是,@Divakar 解决方案要快得多(bsxfun 解决方案大约需要一分钟)- histc 的性能与 accumarray 相同。
    • @Jonas 你可能混淆了accumarray,这是一种矢量化方式,arrayfun/cellfun 只是 for 循环的包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2017-08-30
    • 2020-06-03
    相关资源
    最近更新 更多