不使用唯一函数的单元格数组中最常见的元素?

时间:2015-03-06 03:53:45

标签: arrays matlab indexing cell

你好我有重复字符串和数字(​​类double)的单元格数组对应于字符串。

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

如何计算同名出现的次数和得分总数。例如,约翰的总分为'将会是188.我知道你可以使用独特的功能来做到这一点,但除了使用独特之外还有其他方法可以做到这一点。如果你们可以帮助我,那将是很棒的。

谢谢。

4 个答案:

答案 0 :(得分:2)

我会选择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]

答案 1 :(得分:1)

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

如果名称存储在单元格数组中并且分数存储为向量,则可以执行以下操作:

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)

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

答案 2 :(得分:0)

最近遇到类似问题,发现accumarray。我没有直接使用单元格向量进行测试,但它肯定适用于数值,并且完全符合您的要求。

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

答案 3 :(得分:0)

以下是使用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)