如何找到至少包含矢量 B 的一个元素的单元格 A 的矢量?
How to find the vectors of the cell A that contain at least one element of the vector B?
如何找到至少包含向量 B
一个元素的 A
向量?
示例:
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]}
方法
与 arrayfun
和 ismember
-
Result = A(arrayfun(@(n) any(ismember(B,A{n})),1:numel(A)))
或 arrayfun
和 bsxfun
-
Result = A(arrayfun(@(n) any(any(bsxfun(@eq,B(:),A{n}),2)),1:numel(A)))
或 arrayfun
和 setdiff
-
Result = A(arrayfun(@(n) numel(setdiff(B,A{n})) < numel(B),1:numel(A)))
或 arrayfun
和 intersect
-
Result = A(arrayfun(@(n) ~isempty(intersect(B,A{n})),1:numel(A)))
也可以在这里使用 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))
走不同的路线[使用bsxfun
的屏蔽功能]
与其采用那些本质上是循环方法的基于 arrayfun
或 cellfun
的方法,不如通过将 alot 32=] 转换成二维数值数组。因此,这里的想法是有一个 2D
数组,其中行数是 A
中的最大元素数,列数是 A
中的单元格数。该数组的每一列都将包含 A
的每个单元格中的元素,并且 NaNs
将填充 空白空间 .
采用这种方法的解决方案代码如下所示 -
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));
验证
>> celldisp(Result)
Result{1} =
2 5
Result{2} =
33 77 4
Result{3} =
10 66 17 7 8 11
Result{4} =
15 41 88
基准测试
对于有兴趣查看运行时性能的人,这里有一个具有足够大数据量的快速基准测试 -
%// 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
在我的系统上得到的结果是-
************************ 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.
如您所见,基于 cellfun
的解决方案比基于 arrayfun
的对应解决方案要快一点点!此外,基于掩码的 bsxfun
方法看起来很有趣,但请记住它 需要大量内存的性质 。
如何找到至少包含向量 B
一个元素的 A
向量?
示例:
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]}
方法
与 arrayfun
和 ismember
-
Result = A(arrayfun(@(n) any(ismember(B,A{n})),1:numel(A)))
或 arrayfun
和 bsxfun
-
Result = A(arrayfun(@(n) any(any(bsxfun(@eq,B(:),A{n}),2)),1:numel(A)))
或 arrayfun
和 setdiff
-
Result = A(arrayfun(@(n) numel(setdiff(B,A{n})) < numel(B),1:numel(A)))
或 arrayfun
和 intersect
-
Result = A(arrayfun(@(n) ~isempty(intersect(B,A{n})),1:numel(A)))
也可以在这里使用 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))
走不同的路线[使用bsxfun
的屏蔽功能]
与其采用那些本质上是循环方法的基于 arrayfun
或 cellfun
的方法,不如通过将 alot 32=] 转换成二维数值数组。因此,这里的想法是有一个 2D
数组,其中行数是 A
中的最大元素数,列数是 A
中的单元格数。该数组的每一列都将包含 A
的每个单元格中的元素,并且 NaNs
将填充 空白空间 .
采用这种方法的解决方案代码如下所示 -
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));
验证
>> celldisp(Result)
Result{1} =
2 5
Result{2} =
33 77 4
Result{3} =
10 66 17 7 8 11
Result{4} =
15 41 88
基准测试
对于有兴趣查看运行时性能的人,这里有一个具有足够大数据量的快速基准测试 -
%// 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
在我的系统上得到的结果是-
************************ 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.
如您所见,基于 cellfun
的解决方案比基于 arrayfun
的对应解决方案要快一点点!此外,基于掩码的 bsxfun
方法看起来很有趣,但请记住它 需要大量内存的性质 。