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,如果您认为此回答解决了您的问题,请单击它旁边的勾号,它标记了已回答的问题。我注意到,对于您在堆栈溢出问题上提出的任何问题,您都没有这样做。我能建议你回顾一下你的历史,把你认为已经解决的任何问题都记下来吗?是的,我明天会看一遍。谢谢你指出这一点。如果我明天在这里发布链接,你愿意浏览我的程序吗?