假设我有一个细胞
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
出现的行。
在这个例子中,我应该得到[1 4]
类似B
. 我一直在尝试解决这个问题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) I can't shake the feeling that there is a much more efficient way to solve this problem, but that I'm not seeing it at the moment. :-)