如何更有效地在2D单元阵列中找到元素?

时间:2015-02-27 12:52:42

标签: arrays performance matlab vectorization cell-array

我有一个2D单元格数组如下:

my_cells=
Columns 1 through 11

{1x6 cell}    {1x8 cell}    {1x2 cell}    {1x7 cell}    {1x7 cell}    {1x6 cell}    {1x7 cell}    {1x7 cell}    {1x8 cell}    {1x5 cell}    {1x7 cell}

 Columns 12 through 22

{1x4 cell}    {1x3 cell}    {1x3 cell}    {1x5 cell}    {1x5 cell}    {1x4 cell}    {1x3 cell}    {1x5 cell}    {1x4 cell}    {1x5 cell}    {1x4 cell}

 Columns 23 through 24

{1x6 cell}    {1x1 cell}

这些单元格中的每一个都有如下的多个数组:

my_cells{1}= [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [2x3 double]    [1x3 double]

my_cells{1}{1}= [977.0000    1.0000    0.9231]
my_cells{1}{2}= [286.0000    7.0000    0.9789]
my_cells{2}{1}= [977.0000    1.0000    0.9231]
my_cells{3}{1}= [286.0000    7.0000    0.9789]
my_cells{1}{5}=[949.0000    7.0000    0.9241
                474.0000    4.0000    0.9926]

我想找到,例如,数字977可能在my_cells中出现的第一个元素。但是,如果可能的话,我想避免使用嵌套for循环来提高性能。有一种简单快捷的方法吗? 所以输出就像1,1,1和2,1,1。

效率不高的示例如下:

    number=977;
    for i=1:N
        M=size(my_cells{i},2);
        for j=1:M
            [a,ind]=ismember(number,my_cells{i}{j}(:,1));
            if sum(a)~=0
                ind( ~any(ind,2), : ) = [];
                my_cells{i}{j}(ind,2)=my_cells{i}{j}(ind,2)-1;
            end
        end
    end

1 个答案:

答案 0 :(得分:3)

这应该这样做:

%// Value to check
a = 977;

%// indices of cells containing a at the first place
idx = cellfun(@(x) find(x == a,1) == 1, my_cells)

%// first cell containing a
cellsWith977atFirst = my_cells(idx)

对于

my_cells = { [977 1 2] [2 977 977] [977 2 1] }

它会返回

celldisp(cellsWith977atFirst)

cellsWith977atFirst{1} =   977     1     2
cellsWith977atFirst{2} =   977     2     1

但是我刚看到你的输入实际上是:

my_cells = { {[977 1 2]} {[2 977 977]} {[977 2 1]} }

如果这种存储数据的方式确实有意义,您应该重新考虑。您需要将此案例的代码更改为:

idx = cellfun(@(x) find(cell2mat(x) == a,1) == 1, my_cells)

你可以通过

再次访问my_cells
cellsWith977atFirst = my_cells(idx);

但你可能更喜欢这个

cellsWith977atFirst = cellfun(@cell2mat, my_cells(idx), 'uni',0)

根据您希望输出的确切程度,可能需要稍微改变一下代码。