【问题标题】:Matlab: sorting a vector by the number of time each unique value occursMatlab:按每个唯一值出现的次数对向量进行排序
【发布时间】:2012-11-27 07:19:12
【问题描述】:

我们有 p.e. i = 1:25 迭代。 每个迭代结果都是一个1xlength(N) 元胞数组,其中0<=N<=25。

iteration 1: 4     5     9    10     20     
iteration 2: 3     8     9    13     14      6
...
iteration 25:  1     2    3

我们将所有迭代的结果评估为一个按频率排序的矩阵,每个值按降序重复,如下例所示:

Matrix=
  Columns 1 through 13
    16    22    19    25     2     5     8    14    17    21     3    12    13
     6     5     4     4     3     3     3     3     3     3     2     2     2
  Columns 14 through 23
    18    20     1     6     7     9    10    11    15    23
     2     2     1     1     1     1     1     1     1     1

结果说明:第 1 列:N == 16 出现在 6 次迭代中,第 2 列:N == 22 出现在 5 次迭代中等等。 如果在任何迭代中未显示数字 N(在该范式中为 N == 4、N == 24),则也不会以频率索引为零列出。

我想将每次迭代 (i) 关联到第一个 N 它显示 p.e. N == 9 仅出现在第一次迭代 i = 1 中,而不出现在 i = 2 中,N == 3 仅出现在 i = 2 中,而不出现在 i = 25 中,等等,直到所有 i 与 @ 唯一关联987654340@的。

提前谢谢你。

【问题讨论】:

    标签: matlab unique octave


    【解决方案1】:

    这是一种使用 R2012a 中引入的unique 功能(即,它将索引返回到第一个值)的方法

    %# make some sample data
    iteration{1} = [1 2 4 6];
    iteration{2} = [1 3 6];
    iteration{3} = [1 2 3 4 5 6];
    nIter= length(iteration);
    
    %# create an index vector so we can associate N's with iterations
    nn = cellfun(@numel,iteration);
    idx = zeros(1,sum(nn));
    idx([1,cumsum(nn(1:end-1))+1]) = 1;
    idx = cumsum(idx); %# has 4 ones, 3 twos, 6 threes
    
    %# create a vector of the same length as idx with all the N's
    nVec = cat(2,iteration{:});
    
    %# run `unique` on the vector to identify the first occurrence of each N
    [~,firstIdx] = unique(nVec,'first');
    
    %# create a "cleanIteration" array, where each N only appears once
    cleanIter = accumarray(idx(firstIdx)',firstIdx',[nIter,1],@(x){sort(nVec(x))},{});
    
    cleanIter = 
        [1x4 double]
        [         3]
        [         5]
    
    >> cleanIter{1}
    ans =
         1     2     4     6
    

    【讨论】:

    • 谢谢你这种方法很有教育意义@Jonas。
    【解决方案2】:

    这是另一个使用accumarray 的解决方案。 cmets中的解释

    % example data (from your question)
    iteration{1} = [4     5     9    10     20  ];
    iteration{2} = [3     8     9    13     14      6];
    iteration{3} = [1     2    3];
    niterations = length(iteration);
    
    % create iteration numbers 
    % same as Jonas did in the first part of his code, but using a short loop
    for i=1:niterations
        idx{i} = i*ones(size(iteration{i}));
    end
    
    % count occurences of values from all iterations
    % sort them in descending order
    occurences = accumarray([iteration{:}]', 1);
    [occ val] = sort(occurences, 1, 'descend');
    
    % remove zero occurences and create the Matrix
    nonzero = find(occ);
    Matrix = [val(nonzero) occ(nonzero)]'
    
    Matrix =
    
     3     9     1     2     4     5     6     8    10    13    14    20
     2     2     1     1     1     1     1     1     1     1     1     1
    
    
    % find minimum iteration number for all occurences
    % again, using accumarray with @min function
    assoc = accumarray([iteration{:}]', [idx{:}]', [], @min);
    nonzero = find(assoc);
    result = [nonzero assoc(nonzero)]'
    
    result =
    
     1     2     3     4     5     6     8     9    10    13    14    20
     3     3     2     1     1     2     2     1     1     2     2     1
    

    【讨论】:

    • 感谢您的方法@angainor。
    猜你喜欢
    • 1970-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2017-02-21
    • 1970-01-01
    • 2023-04-04
    相关资源
    最近更新 更多