Matlab 检查单元格中的条目是否在单元格数组中

Matlab 检查单元格中的条目是否在单元格数组中,matlab,cells,Matlab,Cells,假设我有一个手机 A={[3,0],[2,1]} 和一个细胞阵列 B = {[4,-1],[3,0]; [-1,4],[-3,5]; [3,0],[2,1]; [2,1],[-1,4]}. 我想找到A中的第一个或第二个条目都显示在B中的索引,不包括B中A的两个条目都显示的行 在本例中,我应该为B中的行获取类似[14]的内容。我一直在尝试使用cellfun和cell2mat来解决这个问题,但一直步履蹒跚。又快又脏: C=zeros(size(B))

假设我有一个手机

A={[3,0],[2,1]}

和一个细胞阵列

B = {[4,-1],[3,0];      
      [-1,4],[-3,5];
      [3,0],[2,1];
      [2,1],[-1,4]}.
我想找到
A
中的第一个或第二个条目都显示在
B
中的索引,不包括
B
A
的两个条目都显示的行

在本例中,我应该为
B
中的行获取类似
[14]
的内容。我一直在尝试使用
cellfun
cell2mat
来解决这个问题,但一直步履蹒跚。

又快又脏:

C=zeros(size(B));

for i=1:size(C,1);
    for j=1:size(C,2);
        for k=1:length(A);
            C(i,j)=C(i,j)+isequal(B{i,j},A{k}); % Does element k of A match?
        end;
    end;
end;

find(sum(C')==1) % Sums the rows and finds the rows with only one match

我将通过将单元格数组转换为适当维度的数字数组来解决这个问题,然后使用
ismember

以下示例说明了此方法如何在问题中的示例单元阵列上工作:

%# Build the example cell arrays
A = {[3,0], [2,1]};
B = {[4,-1],[3,0];      
     [-1,4],[-3,5];
     [3,0],[2,1];
     [3,0],[3,0];
     [2,1],[-1,4]};

%# Get the number of elements in A, and the length of the first element
K = size(A, 2);
J = length(A{1, 1});

%# Convert cell arrays to usefully shaped numerical matrices
ANumVec = cell2mat(A);
ANum = reshape(ANumVec, K, J)';
BNum = cell2mat(B);

%# Find matches of 1*2 vectors in ANum in sets of two columns of BNum 
I1 = ismember(BNum(:, 1:J), ANum, 'rows');
I2 = ismember(BNum(:, J+1:end), ANum, 'rows');
I3 = ismember(BNum, ANumVec, 'rows');

%# Find all indices where there was exactly 1 match (ie omit cases of no matches and cases of 2 matches)
MainIndex = I1 + I2;
MainIndex(I3) = 0;
Soln = find(MainIndex > 0);
有几点:

1) 此方法查找
B
中所有行的索引,其中
A
的元素位于
B
的第一列或第二列,不包括
A
B
的行完全对应的情况

2) 如果
A
中有多行,此方法将失败。然而,它对
A
作为大小为1*N的单元数组是鲁棒的,其中N表示任意数量的1*2数字向量。因此,可以通过首先将
A
重塑为1*N单元阵列来规避单行限制

3) 使用逻辑运算符
==
测试等效性。这对于浮点数来说是危险的,除非您有理由先验地相信您的输入不会出现任何浮点数错误


4) 我无法摆脱一种感觉,即有一种更有效的方法来解决这个问题,但我目前还没有看到它。:-)

你为什么会得到
[14]
A{1}
显示在
B{1,2}
B{3,1}
中,而
A{2}
显示在
B{1,4}
B{3,2}
中。那么,为什么解决方案是
[14]
?另外,如果你把问题的措辞改为使用整数,那就太好了。十进制数似乎不是问题的关键,而整数更容易观察。解决方案是[14],因为我在B中查找这些值所在的行(除了两者所在的行)。我应该把它改成这样,而不是索引。我要把它改成这样,你想找到B中的哪些行与A中的某个元素(或者至少有一个元素,但不是全部)有一个相同的元素@roldy明白了。我提供了一个合理有效的解决方案。@roldy如果
a
中的第一个条目在
B
的同一行中出现两次,该怎么办?您想从索引列表中包括或排除此情况吗?嗯,希望有一种更紧凑的方法来完成此操作,因为我的数据集可能包含1000个以上的元素。我不想在每个元素上执行这个循环。我将尝试一下,看看它是如何运行的。您可以遍历并找到与
A{1}
匹配的行,然后找到与
A{2}匹配的行
,然后删除两个列表中出现的任何行。这种方法似乎对我有效,但我无法确定,除非我按照第1点中的建议在B中执行行删除。从一开始我就知道我需要这样做,但我将精力集中在代码的其他方面。如果不太麻烦的话,你能描述一下如何包括这个案例吗。如果你想知道A中的值是从B中取出来的,这是在我设置的循环中完成的。本质上,我是在试图通过它们的公共单元格值“连接”这些行。@roldy我已经更新了答案。您可能会将我所做的压缩为更少的行,但是代码的可读性会更低。感谢您的努力和对该方法的解释。我现在会胡闹,但明天我会发布一个完整的程序链接,详细描述我正在做的事情。也许可以找到一种更有效的方法。我也同意可能存在另一种更简单的方法。@roldy ps,如果您认为此回答解决了您的问题,请单击它旁边的勾号,它标记了已回答的问题。我注意到,对于您在堆栈溢出问题上提出的任何问题,您都没有这样做。我能建议你回顾一下你的历史,把你认为已经解决的任何问题都记下来吗?是的,我明天会看一遍。谢谢你指出这一点。如果我明天在这里发布链接,你愿意浏览我的程序吗?