查找矩阵中不同值的行索引
find row indices of different values in matrix
将矩阵 A (n*2) 作为源,将 B 作为包含元素 A 子集的向量,我想找到项目的行索引。
A=[1 2;1 3; 4 5];
B=[1 5];
F=arrayfun(@(x)(find(B(x)==A)),1:numel(B),'UniformOutput',false)
在单元格中给出以下输出 according to this help page
[2x1 double] [6]
按列表示所有出现的索引。但我想要行的索引。即我想知道元素 1 出现在第 1 行和第 2 行中,而元素 5 恰好出现在第 3 行中。如果索引是按行排列的,我可以使用 ceil(F{x}/2) 获得所需的输出.现在行数可变,您建议的解决方案是什么?因为可能碰巧没有完整的包含标签 'rows' in ismember 函数不起作用。此外,我想知道指定元素的所有索引。
在此先感谢您的帮助。
方法一
从当前的 linear-index form into row indices, use mod
转换 F
:
rows = cellfun(@(x) mod(x-1,size(A,1))+1, F, 'UniformOutput', false);
您可以将其与您的代码合并成一行。另请注意,您可以直接使用 B
作为 arrayfun
的输入,并且避免了一个索引阶段:
rows = arrayfun(@(x) mod(find(x==A)-1,size(A,1))+1, B(:), 'UniformOutput', false);
这是如何工作的:
F
您的代码给出的是列优先形式的线性索引。这意味着索引沿着 B
的第一列向下运行,从第二列的顶部开始并再次向下运行,等等。因此可以仅通过模数 (mod
) 获得行号操作。
方法二
使用bsxfun
and accumarray
:
t = any(bsxfun(@eq, B(:), reshape(A, 1, size(A,1), size(A,2))), 3); %// occurrence pattern
[ii, jj] = find(t); %// ii indicates an element of B, and jj is row of A where it occurs
rows = accumarray(ii, jj, [], @(x) {x}); %// group results according to ii
这是如何工作的:
假设 A
和 B
如您的示例所示,t
是 2x3 矩阵
t =
1 1 0
0 0 1
m 第 t
行包含 1
在第 n 列,如果 m-B
的第 n 行出现在 B
的第 n 行。这些值被转换成行和列的形式 find
:
ii =
1
1
2
jj =
1
2
3
这意味着 B
的第一个元素出现在 A
的第 1 行和第 2 行;第二个出现在 B
.
的第 3 行
最后,jj
的值根据 ii
的对应值进行分组(使用 accumarray
)以生成所需的结果。
一种方法 bsxfun
& accumarray
-
%// Create a match of B's in A's with each column of matches representing the
%// rows in A where there is at least one match for each element in B
matches = squeeze(any(bsxfun(@eq,A,permute(B(:),[3 2 1])),2))
%// Get the indices values and the corresponding IDs of B
[indices,B_id] = find(matches)
%// Or directly for performance:
%// [indices,B_id] = find(any(bsxfun(@eq,A,permute(B(:),[3 2 1])),2))
%// Accumulate the indices values using B_id as subscripts
out = accumarray(B_id(:),indices(:),[],@(x) {x})
样本运行-
>> A
A =
1 2
1 3
4 5
>> B
B =
1 5
>> celldisp(out) %// To display the output, out
out{1} =
1
2
out{2} =
3
[r,c] = arrayfun(@(x) find(ismember(A,x)) , B, 'uni',0);
其中 r
给出了您想要的结果,您还可以使用 c
变量来获取 B
中每个数字的列
示例输入的结果:
>> celldisp(r)
r{1} =
1
2
r{2} =
3
>> celldisp(c)
c{1} =
1
1
c{2} =
2
将矩阵 A (n*2) 作为源,将 B 作为包含元素 A 子集的向量,我想找到项目的行索引。
A=[1 2;1 3; 4 5];
B=[1 5];
F=arrayfun(@(x)(find(B(x)==A)),1:numel(B),'UniformOutput',false)
在单元格中给出以下输出 according to this help page
[2x1 double] [6]
按列表示所有出现的索引。但我想要行的索引。即我想知道元素 1 出现在第 1 行和第 2 行中,而元素 5 恰好出现在第 3 行中。如果索引是按行排列的,我可以使用 ceil(F{x}/2) 获得所需的输出.现在行数可变,您建议的解决方案是什么?因为可能碰巧没有完整的包含标签 'rows' in ismember 函数不起作用。此外,我想知道指定元素的所有索引。 在此先感谢您的帮助。
方法一
从当前的 linear-index form into row indices, use mod
转换 F
:
rows = cellfun(@(x) mod(x-1,size(A,1))+1, F, 'UniformOutput', false);
您可以将其与您的代码合并成一行。另请注意,您可以直接使用 B
作为 arrayfun
的输入,并且避免了一个索引阶段:
rows = arrayfun(@(x) mod(find(x==A)-1,size(A,1))+1, B(:), 'UniformOutput', false);
这是如何工作的:
F
您的代码给出的是列优先形式的线性索引。这意味着索引沿着 B
的第一列向下运行,从第二列的顶部开始并再次向下运行,等等。因此可以仅通过模数 (mod
) 获得行号操作。
方法二
使用bsxfun
and accumarray
:
t = any(bsxfun(@eq, B(:), reshape(A, 1, size(A,1), size(A,2))), 3); %// occurrence pattern
[ii, jj] = find(t); %// ii indicates an element of B, and jj is row of A where it occurs
rows = accumarray(ii, jj, [], @(x) {x}); %// group results according to ii
这是如何工作的:
假设 A
和 B
如您的示例所示,t
是 2x3 矩阵
t =
1 1 0
0 0 1
m 第 t
行包含 1
在第 n 列,如果 m-B
的第 n 行出现在 B
的第 n 行。这些值被转换成行和列的形式 find
:
ii =
1
1
2
jj =
1
2
3
这意味着 B
的第一个元素出现在 A
的第 1 行和第 2 行;第二个出现在 B
.
最后,jj
的值根据 ii
的对应值进行分组(使用 accumarray
)以生成所需的结果。
一种方法 bsxfun
& accumarray
-
%// Create a match of B's in A's with each column of matches representing the
%// rows in A where there is at least one match for each element in B
matches = squeeze(any(bsxfun(@eq,A,permute(B(:),[3 2 1])),2))
%// Get the indices values and the corresponding IDs of B
[indices,B_id] = find(matches)
%// Or directly for performance:
%// [indices,B_id] = find(any(bsxfun(@eq,A,permute(B(:),[3 2 1])),2))
%// Accumulate the indices values using B_id as subscripts
out = accumarray(B_id(:),indices(:),[],@(x) {x})
样本运行-
>> A
A =
1 2
1 3
4 5
>> B
B =
1 5
>> celldisp(out) %// To display the output, out
out{1} =
1
2
out{2} =
3
[r,c] = arrayfun(@(x) find(ismember(A,x)) , B, 'uni',0);
其中 r
给出了您想要的结果,您还可以使用 c
变量来获取 B
示例输入的结果:
>> celldisp(r)
r{1} =
1
2
r{2} =
3
>> celldisp(c)
c{1} =
1
1
c{2} =
2