Arrays 在更高效的matlab中求小数组的行索引
我有一个大小为3072 x 2的数组,我想在150000 x 2数组中查找行索引。例如,如果我们有Arrays 在更高效的matlab中求小数组的行索引,arrays,matlab,performance,Arrays,Matlab,Performance,我有一个大小为3072 x 2的数组,我想在150000 x 2数组中查找行索引。例如,如果我们有 A = 2 3 7 1 5 4 8 6 及 然后我想要输出 b = 2 4 7 11 将ismember与'rows'参数一起使用: A = [2 3; 7 1 ; 5 4 ; 8 6 ]; B = [ 1 4;
A =
2 3
7 1
5 4
8 6
及
然后我想要输出
b =
2
4
7
11
将
ismember
与'rows'
参数一起使用:
A = [2 3;
7 1 ;
5 4 ;
8 6 ];
B = [ 1 4;
2 3 ;
4 2;
7 1;
7 9;
0 1;
5 4 ;
14 15 ;
13 10 ;
6 8;
8 6 ];
b = find(ismember(B,A,'rows'))
将
ismember
与'rows'
参数一起使用:
A = [2 3;
7 1 ;
5 4 ;
8 6 ];
B = [ 1 4;
2 3 ;
4 2;
7 1;
7 9;
0 1;
5 4 ;
14 15 ;
13 10 ;
6 8;
8 6 ];
b = find(ismember(B,A,'rows'))
这是一种针对性能的方法-
function out_idx = intersect_index(A,B)
s = max(max(A(:,1),[],1),max(B(:,1),[],1)) + 1;
A1D = A(:,2)*s + A(:,1);
B1D = B(:,2)*s + B(:,1);
BA1D = [B1D ; A1D];
[~,idx] = sort(BA1D);
out_idx = sort(idx(find(idx>numel(B1D))-1));
为了解释一下,我们可以将两个元素的每一行转换为标量,每一行都考虑作为索引元组,从而将输入的1D
版本转换为A1D
和B1D
。然后我们将它们附加到一个数组中:BA1D=[B1D;A1D]
,并获得排序后的索引。由于排序,来自A1D
的索引将具有更高的索引,这表明这些是我们需要寻找的匹配项。这是这里的基本想法
另外,请注意,如果A
或B
中有负数,我们需要在开始时引入min
来计算s
计时和验证
>> % --- Setup inputs
B = randi(100000,150000,2);
B = unique(B,'rows');
A = B(randperm(size(B,1),3072),:);
>> out1 = intersect_index(A,B); % Proposed in this post
>> out2 = find(ismember(B,A,'rows')); % @user2999345's soln
>> all(out1 == out2)
ans =
1
>> tic,find(ismember(B,A,'rows')); toc % @user2999345's soln
Elapsed time is 0.066226 seconds.
>> tic, intersect_index(A,B); toc % Proposed in this post
Elapsed time is 0.010360 seconds.
这是一种针对性能的方法-
function out_idx = intersect_index(A,B)
s = max(max(A(:,1),[],1),max(B(:,1),[],1)) + 1;
A1D = A(:,2)*s + A(:,1);
B1D = B(:,2)*s + B(:,1);
BA1D = [B1D ; A1D];
[~,idx] = sort(BA1D);
out_idx = sort(idx(find(idx>numel(B1D))-1));
为了解释一下,我们可以将两个元素的每一行转换为标量,每一行都考虑作为索引元组,从而将输入的1D
版本转换为A1D
和B1D
。然后我们将它们附加到一个数组中:BA1D=[B1D;A1D]
,并获得排序后的索引。由于排序,来自A1D
的索引将具有更高的索引,这表明这些是我们需要寻找的匹配项。这是这里的基本想法
另外,请注意,如果A
或B
中有负数,我们需要在开始时引入min
来计算s
计时和验证
>> % --- Setup inputs
B = randi(100000,150000,2);
B = unique(B,'rows');
A = B(randperm(size(B,1),3072),:);
>> out1 = intersect_index(A,B); % Proposed in this post
>> out2 = find(ismember(B,A,'rows')); % @user2999345's soln
>> all(out1 == out2)
ans =
1
>> tic,find(ismember(B,A,'rows')); toc % @user2999345's soln
Elapsed time is 0.066226 seconds.
>> tic, intersect_index(A,B); toc % Proposed in this post
Elapsed time is 0.010360 seconds.