简体   繁体   English

Matlab:以独特的方式对矩阵进行排序

[英]Matlab: sorting a matrix in a unique way

I have a problem with sorting some finance data based on firmnumbers. 我在根据公司数量排序一些财务数据时遇到问题。 So given is a matrix that looks like: 所以给出的矩阵看起来像:

[1 3 4 7;
1 2 7 8;
2 3 7 8;]

On Matlab i would like the matrix to be sorted as follows: 在Matlab上我希望矩阵按如下方式排序:

[1 0 3 4 7 0;
1 2 0 0 7 8;
0 2 3 0 7 8;]

So basically every column needs to consist of 1 type of number. 所以基本上每列都需要包含一种类型的数字。

I have tried many things but i cant get the matrix sorted properly. 我尝试了很多东西,但我不能正确地排序矩阵。

A = [1 3 4 7;
     1 2 7 8;
     2 3 7 8;]

%// Get a unique list of numbers in the order that you want them to appear as the new columns
U = unique(A(:))'

%'//For each column (of your output, same as columns of U), find which rows have that number. Do this by making A 3D so that bsxfun compares each element with each element
temp1 = bsxfun(@eq,permute(A,[1,3,2]),U)    

%// Consolidate this into a boolean matrix with the right dimensions and 1 where you'll have a number in your final answer
temp2 = any(temp1,3)

%// Finally multiply each line with U
bsxfun(@times, temp2, U)

So you can do that all in one line but I broke it up to make it easier to understand. 所以你可以在一行中完成所有这些,但我将其分解以使其更容易理解。 I suggest you run each line and look at the output to see how it works. 我建议你运行每一行并查看输出以查看它是如何工作的。 It might seem complicated but it's worthwhile getting to understand bsxfun as it's a really useful function. 它可能看起来很复杂,但是理解bsxfun是值得的,因为它是一个非常有用的功能。 The first use which also uses permute is a bit more tricky so I suggest you first make sure you understand that last line and then work backwards. 第一次使用也使用permute是有点棘手,所以我建议你首先确保你理解最后一行,然后向后工作。

What you are asking can also be seen as an histogram 您要问的也可以看作直方图

 A = [1 3 4 7;
     1 2 7 8;
     2 3 7 8;]
uniquevalues  = unique(A(:))   
N = histc(A,uniquevalues'  ,2)                             %//'               
B = bsxfun(@times,N,uniquevalues')                         %//'
%// bsxfun can replace the following instructions: 
%//(the instructions are equivalent only when each value appears only once per row )
%// B = repmat(uniquevalues', size(A,1),1)                    
%// B(N==0) = 0

Answer without assumptions - Simplified 答案没有假设 - 简化

I did not feel comfortable with my old answer that makes the assumption of everything being an integer and removed the possibility of duplicates, so I came up with a different solution based on @lib's suggestion of using a histogram and counting method. 我对我的旧答案感到不舒服,这使得假设一切都是整数并消除了重复的可能性,所以我想出了一个基于@ lib建议使用直方图和计数方法的不同解决方案。

The only case I can see this not working for is if a 0 is entered. 唯一可以看到这种情况不适用的情况是输入0。 you will end up with a column of all zeros, which one might interpret as all rows initially containing a zero, but that would be incorrect. 你将得到一个全零的列,一个人可能会解释为最初包含零的所有行,但这将是不正确的。 you could uses nan instead of zeros in that case, but not sure what this data is being put into, and if it that processing would freak out. 在这种情况下你可以使用nan而不是zeros ,但是不确定这些数据是什么,以及它是否会处理这些数据。

EDITED EDITED

Includes sorting of secondary matrix, B, along with A. 包括二级矩阵B的排序以及A.

A = [-1 3 4 7 9; 0 2 2 7 8.2; 2 3 5 9 8];
B = [5 4 3 2 1; 1 2 3 4 5; 10 9 8 7 6];

keys = unique(A);
[counts,bin] = histc(A,transpose(unique(A)),2);
A_sorted = cell(size(A,1),1);
for ii = 1:size(A,1)
    for jj = 1:numel(keys)
        temp = zeros(1,max(counts(:,jj)));
        temp(1:counts(ii,jj)) = keys(jj);
        A_sorted{ii} = [A_sorted{ii},temp];
    end
end

A_sorted = cell2mat(A_sorted);
B_sorted = nan(size(A_sorted));
for ii = 1:size(bin,1)
   for jj = 1:size(bin,2)
       idx = bin(ii,jj);
       while ~isnan(B_sorted(ii,idx))
          idx = idx+1; 
       end
       B_sorted(ii,idx) = B(ii,jj);
   end
end
B_sorted(isnan(B_sorted)) = 0

You can create at the beginning a matrix with 9 columns , and treat the values in your original matrix as column indexes. 您可以在开头创建一个包含9列的矩阵,并将原始矩阵中的值视为列索引。

A = [1 3 4 7;
1 2 7 8;
2 3 7 8;]

B = zeros(3,max(A(:)))
for i = 1:size(A,1)
    B(i,A(i,:)) = A(i,:)
end
B(:,~any(B,1)) = []

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM