我在3D矩阵(MATLAB)中识别两个最大值的位置时遇到了问题。假设我的矩阵A
输出如下:
A(:,:,1) =
5 3 5
0 1 0
A(:,:,2) =
0 2 0
8 0 8
A(:,:,3) =
3 0 0
0 7 7
A(:,:,4) =
6 6 0
4 0 0
对于第一个A(:,:,1)
,我想确定第一行的值最高(A=5)
。但我需要两个索引位置,在本例中为1
和3
。这与其他A(:,:,:)
相同。
我搜索了 SO ,但由于我在MATLAB中不好,我找不到通过这个方法来解决这个问题。
请帮我解决这个问题。如果我不需要使用for循环来获得所需的输出,那会更好。
答案 0 :(得分:2)
Shot#1 查找每个3D切片的最大值索引 -
%// Reshape A into a 2D matrix
A_2d = reshape(A,[],size(A,3))
%// Find linear indices of maximum numbers for each 3D slice
idx = find(reshape(bsxfun(@eq,A_2d,max(A_2d,[],1)),size(A)))
%// Convert those linear indices to dim1, dim2,dim3 indices and
%// present the final output as a Nx3 array
[dim1_idx,dim2_idx,dim3_idx] = ind2sub(size(A),idx)
out_idx_triplet = [dim1_idx dim2_idx dim3_idx]
示例运行 -
>> A
A(:,:,1) =
5 3 5
0 1 0
A(:,:,2) =
0 2 0
8 0 8
A(:,:,3) =
3 0 0
0 7 7
A(:,:,4) =
6 6 0
4 0 0
out_idx_triplet =
1 1 1
1 3 1
2 1 2
2 3 2
2 2 3
2 3 3
1 1 4
1 2 4
out_idx_triplet(:,2)
正是您要找的!
Shot#2 查找每个3D切片中最高两个数字的索引 -
%// Get size of A
[m,n,r] = size(A)
%// Reshape A into a 2D matrix
A_2d = reshape(A,[],r)
%// Find linear indices of highest two numbers for each 3D slice
[~,sorted_idx] = sort(A_2d,1,'descend')
idx = bsxfun(@plus,sorted_idx(1:2,:),[0:r-1]*m*n)
%// Convert those linear indices to dim1, dim2,dim3 indices
[dim1_idx,dim2_idx,dim3_idx] = ind2sub(size(A),idx(:))
%// Present the final output as a Nx3 array
out_idx_triplet = [dim1_idx dim2_idx dim3_idx]
out_idx_triplet(:,2)
正是您要找的!
答案 1 :(得分:1)
以下代码为您提供相应最大值的列和行。
第一步将获得包含第一维和第二维的每个子矩阵的最大值。由于max默认使用第一个维度,因此矩阵被重新整形以组合原始的第一维和第二维。
max_vals = max(reshape(A,size(A,1)*size(A,2),size(A,3)));
max_vals =
5 8 7 6
在第二步中,使用max_vals
在第三维上获得等于每个子矩阵的相应arrayfun
的元素的索引。由于arrayfun
的输出是单元格,cell2mat
用于将输出转换为矩阵。最后一步,find
的线性索引由ind2sub
转换为子索引。
[i,j] = ind2sub(size(A(:,:,1)),cell2mat(arrayfun(@(i)find(A(:,:,i)==max_vals(i)),1:size(A,3),'UniformOutput',false)))
i =
1 2 2 1
1 2 2 1
j =
1 1 2 1
3 3 3 2
因此,j
中的值是您想要的值。