更改代码以适应字符串 - Matlab

时间:2014-07-06 15:45:58

标签: string matlab count group-by cell-array

我有以下代码:

NI1=[NI{:,1} NI{:,2} NI{:,3}];
[~,NI2]=sort(NI1(:,2));
NI1=NI1(NI2,:);
NI1((NI1(:,3) == 0),:) = [];
NI1=unique(NI1(:,1:3),'rows');
NI3= unique(NI1(:,1:2),'rows')

for mj=1:size(NI3,1)
    NI3(mj,3)=sum(NI1(:,1) == NI3(mj,1) & NI1(:,2)==NI3(mj,2));
end

我的初始单元阵列NI1有列:1)年份; 2)对应于银行的代码3)对应于银行工人的代码。示例:

c1      c2  c3
1997    3   850
1997    3   1024
1997    3   5792

我的输出NI3计算了不同年份(c1)在每个银行(c2)中工作的分析师(c3)的数量,例如:

c1      c2  c3
1997    3   14
1997    7   84
1997    11  15
1998    4   1
1998    15  10
1998    3   12
1999    11  17

现在我尝试应用完全相同的代码,但我的最后一列(c3)是一个字符串,所以初始单元格数组fir_ins如下:

1997    3   'ACAD'
1997    3   'ADCT'
1997    3   'ADEX'

我想获得与NI3完全相同的输出,但我必须更改代码,因为我的上一列是一个字符串。

我只是错过了最后一部分,这是我到目前为止的代码。

ESTIMA=num2cell(I{:,6});
ANALY=num2cell(I{:,7});
YEAR = num2cell(T_ANNDAT3);
fir_ins=[YEAR ESTIMA I{:,1}];
fir_ins= sortrows(fir_ins,2);
[~, in2,~] = unique(strcat(fir_ins(:,2),fir_ins(:, 3)));
fir_ins = fir_ins(in2,:);
fir_ins= sortrows(fir_ins,[1 2]);
fir_ins2=fir_ins(:,1:2);
fir_ins2=unique(cell2mat(fir_ins2(:,1:2)),'rows');

这部分不起作用:

for jm=1:size(fir_ins2,1)
    fir_ins2(jm,3)=sum(cell2mat(fir_ins(:,1))) == fir_ins2(jm,1) & cell2mat(fir_ins(:,2))==cell2mat(fir_ins2(jm,2));
end

1 个答案:

答案 0 :(得分:2)

您可以执行此操作"聚合"在accumarray函数的帮助下更有效率。我们的想法是将前两列(行主键)映射到下标(索引从1开始),然后将这些下标传递给accumarray进行计数。

下面是一个例子来说明。首先,我首先生成一些类似于你的随机数据:

% here are the columns
n = 150;
c1 = sort(randi([1997 1999], [n 1]));           % years
c2 = sort(randi([3 11], [n 1]));                % bank code
c3 = randi(5000, [n 1]);                        % employee ID as a number
c4 = cellstr(char(randi(['A' 'Z']-0, [n,4])));  % employee ID as a string

% combine records (NI)
X = [c1 c2 c3];                                 % the one with numeric worker ID
X2 = [num2cell([c1 c2]) c4]; % {c1 c3 c4}       % the one with string worker ID

请注意,就我们的目的而言,如果worker ID列表示为数字或字符串,则无关紧要;我们不会使用它们,只有前两列表示"主键"使用的行:

% find the unique primary keys and their subscript mapping
[years_banks,~,ind] = unique([c1 c2], 'rows');

% count occurences (as in SQL: SELECT COUNT(..) FROM .. GROUPT BY ..)
counts = accumarray(ind, 1);

% build final matrix: years, bank codes, counts
M = [years_banks counts];

我的假数据得到了以下结果:

>> M
M =
        1997           3          13
        1997           4          11
        1997           5          15
        1997           6          14
        1997           7           4
        1998           7          11
        1998           8          24
        1998           9          15
        1999           9           1
        1999          10          22
        1999          11          20