不使用 unique 函数的元胞数组中出现频率最高的元素?

most frequent element in a cell array without using unique function?

你好,我有重复字符串和对应于字符串的数字(class 双精度)的元胞数组。

Name     Score
 'John'    90
 'Mat'     99
 'John'    98
 'Tonny'   88
 'Carl'    99
 'Rem'     88
 'Tonny'   99

如何计算相同名字出现的次数和总分。例如 'John' 的总分将是 188。我知道你可以使用 unique 函数来做到这一点,但是除了使用 unique 之外还有其他方法可以做到这一点。如果你们能帮助我,那就太好了。

谢谢。

您的答案将取决于数据的存储方式。

如果姓名存储在元胞数组中,分数存储为向量,您可以执行以下操作:

names = {'John', 'Mat', 'John', 'Tonny', 'Carl', 'Rem', 'Tonny'}
scores = [90, 99, 98, 88, 99, 88, 99]
ref_mat = cellfun(@(x) strcmp(names,x),names,'UniformOutput',false)
tot_score = cellfun(@(x) sum(scores(x)), ref)

在这里,您将创建匹配名称的索引垫,然后引用这些分数并对它们求和。总分将根据每个名字计算,因此重复的名字会有重复的总分。这样您就不必找到唯一值。

最近遇到了类似的问题,找到了accumarray。我没有直接使用元胞向量对其进行测试,但它绝对适用于数值并且完全符合您的要求。

names = [1,2,1,3,4,5,3]
scores = [90, 99, 98, 88, 99, 88, 99]
counts = accumarray(names,scores)

我会选择 uniqueaccumarray。但是如果你想避免unique,你可以这样做:

% // Data:
data = { 'John'    90
         'Mat'     99
         'John'    98
         'Tonny'   88
         'Carl'    99
         'Rem'     88
         'Tonny'   99}

%// Generate unique numeric labels without `unique`
N = size(data,1);
[ii, jj] = ndgrid(1:N);
[~, ind] = max(triu(reshape(strcmp(data(ii,1), data(jj,1)), N, N)));
ind = ind([true diff(ind)>0]);

%// Apply `accumarray` to that:
s = accumarray(ind(:), [data{:,2}].', [], @sum, NaN);
ind = ind([true diff(ind)>0]);
result = [data(ind,1) num2cell(s(~isnan(s)))];

在这个例子中,

result = 
    'John'     [188]
    'Mat'      [ 99]
    'Tonny'    [187]
    'Carl'     [ 99]
    'Rem'      [ 88]

这是一个使用accumarray

的解决方案
names = {'John', 'Mat', 'John', 'Tonny', 'Carl', 'Rem', 'Tonny'}
scores = [90, 99, 98, 88, 99, 88, 99]
[uniquenames,b,c]=unique(names,'stable')
counts = accumarray(c,scores)