MATLAB:列联表

时间:2013-11-14 01:17:16

标签: matlab

我有一个以下类型的单元格数组:

 datABC =
           [45]  [67]  'A'
           [34]  [44]  'A'
           [11]  [84]  'A'
           [23]  [68]  'A'
           [34]  [44]  'B'
           [30]  [94]  'B'
           [304]  [414]  'C'
           [78]  [110]  'C'
           [34]  [120]  'C'

现在我必须根据AB&和C计算观察次数和第一和第二列的平均值。 {{1}}。

提前致谢。

3 个答案:

答案 0 :(得分:2)

看到闸门被打开,我不妨投入两美分。

带循环的解决方案运行良好,但您也可以消除循环,但会牺牲可读性。首先,您可以使用unique获取最后一列中的唯一值:

stringKeys = unique(datABC(:,3))'

然后,您可以使用anonymous functioncellfun来计算每个密钥的出现次数:

memberFun = @(x) ismember(datABC(:,3),x);
keyOccurrences = cellfun(@(x) nnz(memberFun(x)),stringKeys)

要计算前两列中每一列的相应数据的平均值,您可以再次使用具有非均匀输出的cellfun

colMeanFun = @(x) mean(reshape([datABC{memberFun(x),1:2}],[],2),1);
colMeans = cellfun(colMeanFun,stringKeys,'UniformOutput',false);
colMeans = vertcat(colMeans{:})

还可以看一下strcmpmi,它可以用来代替ismember,但会忽略大小写。

测试数据

datABC = {[45]  [67]  'A'; [34]  [44]  'A'; [11]  [84]  'A'; ...
          [23]  [68]  'A'; [34]  [44]  'B'; [30]  [94]  'B'; ...
          [304] [414] 'C'; [78]  [110] 'C'; [34]  [120] 'C'}; % 9-by-3

答案 1 :(得分:2)

看起来像accumarray的作业:

[categories ii jj] = unique(dataABC(:,3));
num = histc(jj,1:max(jj));
mean1 = accumarray(jj, cell2mat(dataABC(:,1)), [], @mean);
mean2 = accumarray(jj, cell2mat(dataABC(:,2)), [], @mean);

示例:

>> dataABC{4,2}

dataABC = 

    [1]    [10]    'A' 
    [2]    [-5]    'B' 
    [3]    [15]    'A' 
    [4]    [40]    'CC'

给出

categories = 

    'A'
    'B'
    'CC'

>> num

num =

     2
     1
     1

>> mean1

mean1 =

     2
     2
     4

>> mean2

mean2 =

   12.5000
   -5.0000
   40.0000

答案 2 :(得分:1)

熟悉logical indexing

for x = unique(datABC(:,3))'
    idx = strcmp(x, datABC(:, 3));
    disp([x{1} ': ' num2str(sum(idx)) ' observations'])
    disp(mean(cell2mat(datABC(idx, 1:2))))
end