Matlab:按照每个唯一值出现的时间排序向量

时间:2012-11-26 16:18:03

标签: matlab unique octave

我们有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 == 4N == 24中),则列出的频率索引也不为零。

我想将每次迭代(i)与显示的第一个N相关联。 N == 9仅出现在第一次迭代中i = 1而不出现在i = 2中,N == 3仅出现在i = 2而不出现在i = 25等等所有i都与N的唯一关联。

提前谢谢。

2 个答案:

答案 0 :(得分:2)

这是一种使用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

答案 1 :(得分:1)

以下是使用accumarray的另一种解决方案。评论中的解释

% 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