【问题标题】:Sort and keep index of a n-dimension array -- MATLAB排序并保留 n 维数组的索引 - MATLAB
【发布时间】:2014-12-27 00:15:18
【问题描述】:

我有一个 12 维数组,并且在优化问题中使用每个维度作为索引值。

A(:,:,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10)

每个索引值i是一个从1到5的值。

我想将A 从大到小排序并跟踪索引,以便我知道哪些索引对应于A 的哪个值。

所以我的理想输出将是一个 2 列单元格/数组,其中一列是值,另一列是索引值。

对于一个简单的 3D 示例:假设我有一个 3D 数组:A(:,:,i1)

地点:

A(:,:,1) =  2 
A(:,:,2) =  6 
A(:,:,3) =  13 
A(:,:,4) =  11 
A(:,:,5) =  5  

我希望我的输出是:

13   3
11   4
6    2
5    5
2    1

编辑:

假设我有 1x1x3x3 大小的输入,这样

A(1,1,1,1) = 3

A(1,1,2,1) = 1

A(1,1,3,1) = 23

A(1,1,1,2) = 12

A(1,1,2,2) = 9

A(1,1,3,2) = 8

A(1,1,1,3) = 33

A(1,1,2,3) = 14

A(1,1,3,3) = 6

预期的输出是:

33 [1,1,1,3]

23 [1,1,3,1]

14 [1,1,2,3]

12 [1,1,1,2]

9 [1,1,2,2]

8 [1,1,3,2]

6 [1,1,3,3]

3 [1,1,1,1]

1 [1,1,2,1]

【问题讨论】:

  • 那么输出 2 列数组的大小是多少?那就是它有多少行?
  • 它将是 prod(size(A)),即 9765625
  • 您能否以一个小的 3D 数组而不是 12 维数组为例,向我们展示预期的输出?
  • 我编辑了评论举个例子
  • 很抱歉再次打扰,但没有那么简单。你能假设2 x 2 x 2 大小的输入吗?或者你的意思是你总是有1 x 1 x M x .. 作为输入?

标签: arrays matlab sorting indexing n-dimensional


【解决方案1】:

这应该是任何多维输入数组的通用代码 -

%// Sort A and get the indices
[sorted_vals,sorted_idx] = sort(A(:),'descend'); 

%// Set storage for indices as a cell array and then store sorted indices into it
c = cell([1 numel(size(A))]); 
[c{:}] = ind2sub(size(A),sorted_idx);

%// Convert c to the requested format and concatenate with cell arary version of 
%// sorted values for the desired output
out = [num2cell(sorted_vals) mat2cell([c{:}],ones(1,numel(A)),numel(size(A)))]; 

通用代码感谢this fine solution

【讨论】:

  • 这对我来说也是同样的问题。有什么方法可以让这段代码适用于可变维度?由于您还必须指定[p1,...,p12]
  • @Divakar 非常感谢,这非常有效!现在我只是想找出一种方法来可视化/显示这些数据。
  • @OliverOliver 不是用于显示您的数据的单元格,例如,在我的回答中,单元格 yourCell?
  • @Parag S. Chandakkar 是的,是的。我只是在大声思考。我的下一步是在绘图或其他东西中显示此输出以使其超级容易可视化。
  • @ParagS.Chandakkar 查看有关如何使其通用的编辑。
【解决方案2】:

我想这就是你想要的:

b=A(:);
[sorted_b,ind]=sort(b,'descend');
[dim1,dim2,dim3,dim4]=ind2sub(size(A),ind);

%arranging in the form you want
yourCell=cell(size(b,1),2);
yourCell(:,1)=mat2cell(sorted_b,ones(size(b,1),1),1);

%arranging indices -> maybe vectorized way is there for putting values in "yourCell"
for i=1:size(b,1)
    yourCell{i,2}=[dim1(i) dim2(i) dim3(i) dim4(i)];
end

对于数组A,你给的,我的输出是这样的:

33  [1,1,1,3]
23  [1,1,3,1]
14  [1,1,2,3]
12  [1,1,1,2]
9   [1,1,2,2]
8   [1,1,3,2]
6   [1,1,3,3]
3   [1,1,1,1]
1   [1,1,2,1]

与您的输出相匹配。

【讨论】:

  • 尝试提取索引时出现问题。我在尝试 11 维数组时得到了 [3,3,12,2420] 的索引输出
  • 告诉你矩阵的确切大小,如m x n x p x...
  • [1 x 1 x 4 x 4 x 4 x 4 x 4 x 4 x 4 x 4 x 4]
  • 现在我明白了,我的代码可以正常工作,但它要求您指定尽可能多的 no。变量作为您的矩阵维数,即如果您的矩阵是 4-D。然后你应该把[row,col,layer]=ind2sub(size(a),ind);改成[dim1,dim2,dim3,dim4]=ind2sub(size(a),ind);,把yourCell{i,2}=[row(i) col(i) layer(i)];改成yourCell{i,2}=[dim1(i) dim2(i) dim3(i) dim4(i)];。因此,如果您输入可变维度数组,即 12-D、11-D 等,我的代码将不起作用。请参阅修改后的代码。它适用于 4-D 数组,如果您按照我的建议编写 [dim1,dim2,...,dim11],它将适用于 11-D 数组。
  • 已经为您+1,如果需要,您可以使用通用部分。这并不是我的代码的重要组成部分。
猜你喜欢
  • 2015-06-26
  • 2019-08-17
  • 2017-07-12
  • 2017-04-28
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2021-08-06
  • 1970-01-01
相关资源
最近更新 更多