【问题标题】:most frequent element in a cell array without using unique function?不使用唯一函数的单元格数组中最常见的元素?
【发布时间】:2015-03-06 03:53:44
【问题描述】:

您好,我有重复字符串和与字符串对应的数字(双精度类)的单元格数组。

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

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

谢谢。

【问题讨论】:

    标签: arrays matlab indexing cell


    【解决方案1】:

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

    【讨论】:

    • 或者,如果您有权访问统计工具箱,grp2idx 将为您创建数字标签,而无需显式调用 unique: [numericIndex, correspondingNames] = grp2idx(data(:,1));
    • 谢谢!我不知道这个功能。但是,猜猜它在内部调用了什么函数? :-)
    • 这就是我评论中“显式”一词的来源:)
    【解决方案2】:

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

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

    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)
    

    在这里,您将创建一个匹配名称的索引垫,然后参考这些分数并将它们相加。总分是针对每个名字的,所以重复的名字会有重复的总分。这样您就不必找到唯一值。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • accumarray 绝对是要走的路(+1)。但是,它不适用于元胞数组 (-1)。查看@LuizMendo 的解决方案。
        猜你喜欢
        • 2015-02-21
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多