简体   繁体   English

如何找到包含至少一个向量B的元素的单元格A的向量?

[英]How to find the vectors of the cell A that contain at least one element of the vector B?

How to find the vectors of A that contain at least one element of the vector B ? 如何找到包含至少一个向量B元素的A向量?

example: 例:

A = {[2 5],[8 9 2],[33 77 4],[102 6],[10 66 17 7 8 11],[110 99],[1 4 3],[15 41 88]}

B = [5 77 41 66 7]

Result = {[2 5],[33 77 4],[10 66 17 7 8 11],[15 41 88]}

Approaches 途径

With arrayfun and ismember - 使用arrayfunismember -

Result = A(arrayfun(@(n) any(ismember(B,A{n})),1:numel(A)))

Or with arrayfun and bsxfun - 或者使用arrayfunbsxfun -

Result = A(arrayfun(@(n) any(any(bsxfun(@eq,B(:),A{n}),2)),1:numel(A)))

Or with arrayfun and setdiff - 或者使用arrayfunsetdiff -

Result = A(arrayfun(@(n) numel(setdiff(B,A{n})) < numel(B),1:numel(A)))

Or with arrayfun and intersect - 或者使用arrayfunintersect -

Result = A(arrayfun(@(n) ~isempty(intersect(B,A{n})),1:numel(A)))

One could also use cellfun here, such that the four counterpart cellfun based solutions end up like these - 人们也可以在这里使用cellfun ,这样四个基于cellfun的对应解决方案最终会像这样 -

Result = A(cellfun(@(x) any(ismember(B,x)), A))

Result = A(cellfun(@(x) any(any(bsxfun(@eq,B(:),x),2)),A))

Result = A(cellfun(@(x) numel(setdiff(B,x)) < numel(B),A))

Result = A(cellfun(@(x) ~isempty(intersect(B,x)),A))

Taking different route [Using bsxfun 's masking capability] 采取不同的路线[使用bsxfun的掩蔽能力]

Rather than going into those arrayfun or cellfun based approaches that are essentially loopy approaches, one can make the solution alot vectorized by converting A into a 2D numeric array. 不是进入那些基本上是循环方法的基于arrayfuncellfun的方法,而是可以通过将A转换为2D数值阵列来使解决方案很多 So, the idea here is to have a 2D array in which number of rows is the maximum number of elements in A and number of columns as number of cells in A . 因此,这里的想法是有一个2D数组,其中行数是A中元素的最大数量,列数是A中单元格的数量。 Each column of this array would hold elements from each cell of A and NaNs would fill up the empty spaces . 该数组的每一列都将保存A每个单元格中的元素,并且NaNs将填充空白空间

The solution code with such an approach would look like this - 使用这种方法的解决方案代码看起来像这样 -

lens = cellfun('length',A); %// number of elements in each cell of A
mask = bsxfun(@ge,lens,(1:max(lens))'); %//'# mask of valid places in the 2D array
A_arr = NaN(size(mask)); %//initialize 2D array in which A elements are to be put
A_arr(mask) = [A{:}]; %// put the elements from A

%// Find if any element from B is in any element along the row or dim-3       
%// locations in A_arr. Then logically index into A with it for the final
%// cell array output
Result = A(any(any(bsxfun(@eq,A_arr,permute(B,[1 3 2])),1),3));

Verification 验证

>> celldisp(Result)
Result{1} =
     2     5
Result{2} =
    33    77     4
Result{3} =
    10    66    17     7     8    11
Result{4} =
    15    41    88

Benchmarking 标杆

For people interested in seeing the runtime performances, here's a quick benchmarking test with a sufficiently huge datasize - 对于有兴趣了解运行时性能的人来说,这是一个快速的基准测试,具有足够大的数据量 -

%// Create inputs
N = 10000; %// datasize
max_num_ele = 100; %// max elements in any cell of A
num_ele = randi(max_num_ele,N,1); %// number of elements in each cell of A
A = arrayfun(@(n) randperm(N,num_ele(n)), 1:N, 'uni', 0); 
B = randperm(N,num_ele(1));

%// Warm up tic/toc.
for k = 1:100000
    tic(); elapsed = toc();
end

%// Start timing all approaches
disp('************************  With arrayfun **************************')
disp('------------------------  With arrayfun + ismember')
tic
Result = A(arrayfun(@(n) any(ismember(B,A{n})),1:numel(A)));
toc, clear Result

disp('------------------------  With arrayfun + bsxfun')
tic
Result = A(arrayfun(@(n) any(any(bsxfun(@eq,B(:),A{n}),2)),1:numel(A)));
toc, clear Result

disp('------------------------  With arrayfun + setdiff')
tic
Result = A(arrayfun(@(n) numel(setdiff(B,A{n})) < numel(B),1:numel(A)));
toc, clear Result

disp('------------------------  With arrayfun + intersect')
tic
Result = A(arrayfun(@(n) ~isempty(intersect(B,A{n})),1:numel(A)));
toc, clear Result

disp('************************  With cellfun **************************')
disp('------------------------  With cellfun + ismember')
tic
Result = A(cellfun(@(x)any(ismember(B,x)), A));
toc, clear Result

disp('------------------------  With cellfun + bsxfun')
tic
Result = A(cellfun(@(x) any(any(bsxfun(@eq,B(:),x),2)),A));
toc, clear Result

disp('------------------------  With cellfun + setdiff')
tic
Result = A(cellfun(@(x) numel(setdiff(B,x)) < numel(B),A));
toc, clear Result

disp('------------------------  With cellfun + setdiff')
tic
Result = A(cellfun(@(x) ~isempty(intersect(B,x)),A));

disp('************************  With masking bsxfun **************************')
tic
lens = cellfun('length',A); %// number of elements in each cell of A
mask = bsxfun(@ge,lens,(1:max(lens))'); %//'
A_numarr = NaN(size(mask));
A_numarr(mask) = [A{:}];
Result = A(any(any(bsxfun(@eq,A_numarr,permute(B,[1 3 2])),1),3));
toc

The results thus obtained on my system were - 在我的系统上获得的结果是 -

************************  With arrayfun **************************
------------------------  With arrayfun + ismember
Elapsed time is 0.409810 seconds.
------------------------  With arrayfun + bsxfun
Elapsed time is 0.157327 seconds.
------------------------  With arrayfun + setdiff
Elapsed time is 1.154602 seconds.
------------------------  With arrayfun + intersect
Elapsed time is 1.081729 seconds.
************************  With cellfun **************************
------------------------  With cellfun + ismember
Elapsed time is 0.392375 seconds.
------------------------  With cellfun + bsxfun
Elapsed time is 0.143341 seconds.
------------------------  With cellfun + setdiff
Elapsed time is 1.101331 seconds.
------------------------  With cellfun + setdiff
************************  With masking bsxfun ********************
Elapsed time is 0.067224 seconds.

As one can see, cellfun based solutions are wee bit faster than their arrayfun based counterparts! 正如人们所看到的, cellfun基础的解决方案比他们快凌晨一点arrayfun基于同行! Also, mask-based bsxfun approach looks like an interesting one, but do keep in mind it's memory-hungry nature . 此外,基于掩码的bsxfun方法看起来很有趣,但请记住它的内存饥饿性

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对于单元格A的每个向量,如何查找单元格B的向量中不包含的所有可能组成部分的组合? - For each vector of the cell A, How to find all possible combinations of its components that are not contained in vectors of the cell B? 如何从属于A的单元格B中删除所有向量或从A中包含在一个向量中的向量? - How to remove all vectors from a cell B which belong to A or which are contained in one vector from A? 如何在Matlab中从包含目标向量的数字单元格中找到行? - how to find row from numeric cell that contain target vector in Matlab? 如何在向量中找到一个零元素 - How to find one zero element in a vector 如何找到具有至少一个非零元素的列的索引? - How to find the index of columns with at least one non-zero element? 如何在Matlab中查找重复的细胞向量? - How to find repeated cell vectors in matlab? 如何建立一个元素一个元素的矢量? - How to build a vector one element by one element? 我如何从两个向量中找到一个150 * 25的矩阵,使得每个向量元素与另一个暗1 * 150&1 * 25向量的元素相乘? - How do i find a matrix of 150*25 from two vectors such that each vector elements multiply with each element of another vector of dim 1*150 &1*25? 如何在复杂单元格中查找元素? - How to find an element in a complex cell? 如何在Matlab中查找单元格的索引(向量格) - How to find the index of a cell (vector case) in Matlab
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM