将 ismember 扩展到单元格
Extending ismember to cells
我搜索了论坛,但没有找到足够的信息来帮助我解决这个问题。
考虑集合(向量元胞)
A = {[1],[1 2],[2],[1 2 3],[1 2 3 4],[1 3]}
我想构造一个矩阵 B 看起来像
B = [1 1 0 1 1 1
0 1 0 1 1 0
0 1 1 1 1 0
0 0 0 1 1 0
0 0 0 0 1 0
0 0 0 1 1 1]
矩阵 B 指定向量相对于彼此的从属关系。也就是说,第一行查看 A 中的第一个元素 [1],并检查它是否是其他向量的成员,如果是成员则放置 1,否则放置 0。
我可以使用两个 for 循环来做到这一点:一个遍历 A 的元素,另一个嵌套,用于 A 的每个元素,检查相对于 A 的每个其他成员的成员资格。
我想避免使用 for 循环。有没有从A得到B的矢量化方案?
对于元胞数组,很难避免循环,或者它们的表亲 cellfun
。我会这样做:
[ii, jj] = ndgrid(1:numel(A)); % indices of all possible pairs
result = cellfun(@(x,y) all(ismember(x,y)), A(ii), A(jj)); % see if all elements in the
% first are present in the second
好吧,这是您自找的,所以这里有一个几乎*矢量化的解决方案,使用 bsxfun
and permute
-
lens = cellfun('length',A)
vals = [A{:}]
mask = bsxfun(@ge,lens,[1:max(vals)]')
a = nan(size(mask))
a(mask) = vals
matches = bsxfun(@eq,a,permute(a,[3,4,1,2]));
out = bsxfun(@eq,squeeze(sum(any(matches,3),1)),lens(:))
*: 几乎是因为在 cellfun('length',A)
开始时使用了 cellfun
,但由于它只是获取那里的单元格的长度,因此在计算上可以忽略不计。
另请注意,此方法会占用大量内存资源,因此可能没有任何好处,但尽可能尊重矢量化解决方案的要求!
我搜索了论坛,但没有找到足够的信息来帮助我解决这个问题。
考虑集合(向量元胞)
A = {[1],[1 2],[2],[1 2 3],[1 2 3 4],[1 3]}
我想构造一个矩阵 B 看起来像
B = [1 1 0 1 1 1
0 1 0 1 1 0
0 1 1 1 1 0
0 0 0 1 1 0
0 0 0 0 1 0
0 0 0 1 1 1]
矩阵 B 指定向量相对于彼此的从属关系。也就是说,第一行查看 A 中的第一个元素 [1],并检查它是否是其他向量的成员,如果是成员则放置 1,否则放置 0。
我可以使用两个 for 循环来做到这一点:一个遍历 A 的元素,另一个嵌套,用于 A 的每个元素,检查相对于 A 的每个其他成员的成员资格。
我想避免使用 for 循环。有没有从A得到B的矢量化方案?
对于元胞数组,很难避免循环,或者它们的表亲 cellfun
。我会这样做:
[ii, jj] = ndgrid(1:numel(A)); % indices of all possible pairs
result = cellfun(@(x,y) all(ismember(x,y)), A(ii), A(jj)); % see if all elements in the
% first are present in the second
好吧,这是您自找的,所以这里有一个几乎*矢量化的解决方案,使用 bsxfun
and permute
-
lens = cellfun('length',A)
vals = [A{:}]
mask = bsxfun(@ge,lens,[1:max(vals)]')
a = nan(size(mask))
a(mask) = vals
matches = bsxfun(@eq,a,permute(a,[3,4,1,2]));
out = bsxfun(@eq,squeeze(sum(any(matches,3),1)),lens(:))
*: 几乎是因为在 cellfun('length',A)
开始时使用了 cellfun
,但由于它只是获取那里的单元格的长度,因此在计算上可以忽略不计。
另请注意,此方法会占用大量内存资源,因此可能没有任何好处,但尽可能尊重矢量化解决方案的要求!