2015-07-28 95 views
3

在matlab/octave中使用sort函数根据元素的相对频率对数组进行排序可能吗?按数组元素的频率对数组元素进行排序

例如阵列

m= [4,4,4,10,10,10,4,4,5] 

应导致该数组中:

[5,10,10,10,4,4,4,4,4] 

5是较不频繁的元素,是在顶部而4是最常见的,它的上底部。 应该使用histcount提供的索引吗?

回答

3

一种方法是使用accumarray找到每个数字的计数(我怀疑你可以使用histcounts(m,max(m)))但你必须清除所有的0 S)。

m = [4,4,4,10,10,10,4,4,5]; 

[~,~,subs]=unique(m); 
freq = accumarray(subs,subs,[],@numel); 
[~,i2] = sort(freq(subs),'descend'); 

m(i2) 

通过combinging我与的m.s.方法,您可以得到一个简单的解决方案:

m = [4,4,4,10,10,10,4,4,5]; 

[U,~,i1]=unique(m); 
freq= histc(m,U); 
[~,i2] = sort(freq(i1),'descend'); 

m(i2) 
3

下面的代码首先计算多久每个元素出现,然后使用runLengthDecode扩大独特元素。

m = [4,4,4,10,10,10,4,4,5]; 

u_m = unique(m); 

elem_count = histc(m,u_m); 
[elem_count, idx] = sort(elem_count); 

m_sorted = runLengthDecode(elem_count, u_m(idx)); 

runLengthDecode定义是从this answer复制:

对于MATLAB R2015a +:R2015a之前

function V = runLengthDecode(runLengths, values) 
if nargin<2 
    values = 1:numel(runLengths); 
end 
V = repelem(values, runLengths); 
end 

适用版本:

function V = runLengthDecode(runLengths, values) 
%// Actual computation using column vectors 
V = cumsum(accumarray(cumsum([1; runLengths(:)]), 1)); 
V = V(1:end-1); 
%// In case of second argument 
if nargin>1 
    V = reshape(values(V),[],1); 
end 
%// If original was a row vector, transpose 
if size(runLengths,2)>1 
    V = V.'; %' 
end 
end 
+0

你应该张贴'runlegnthDecode'实际的代码在你的答案中除了链接,您已经有...也注意'repelem'是一个相当新近的功能,所以这不适用于老版本的Matlab(但它并不难)。虽然通过结合我们的两个答案,你可以避免使用'runlengthDecode',只需使用排序... – Dan

+0

@Dan我从原来的答案复制代码;它不一定依赖'repelem'。 –

2

你可以指望的重复与bsxfunsort的是,并应用排序,以m数:

[~, ind] = sort(sum(bsxfun(@eq,m,m.'))); 
result = m(ind);