我有一个600 000行和5列的单元格数组。在以下示例中,我仅提供3个不同的代码和5年的时间段。输入:
c1 c2 c3 c4 c5
1 2006 20060425 559 'IA'
1 2007 20070129 559 'LO'
1 2007 20070826 559 'VC'
1 2008 20080825 34 'VP'
1 2009 20090116 34 'ZO'
4 2007 20070725 42 'OI'
4 2008 20080712 42 'TF'
4 2008 20080428 42 'XU'
11 2007 20070730 118 'AM'
11 2008 20080912 118 'HK'
11 2009 20090318 2 'VT'
11 2010 20100121 2 'ZZ'
我想获得一个新变量,它为每个代码(c1
)提供样本中c1
出现的年份和相应的c4
值。例如:
输出:
x 2006 2007 2008 2009 2010
1 559 559 34 34 -
4 - 42 42 - -
11 - 118 118 2 2
要访问我的单元格数组,这是我到目前为止使用的代码:
a1=T_ANNDAT3;
a2=I{:,7};
a3=I{:,6};
a4=I{:,16};
a5=I{:,1};
TRACK_AN = [num2cell([a2 a1 a4 a3]) a5];
TRACK_AN(cell2mat(TRACK_AN(:,1))==0,:)=[];
[~,indTA,~] = unique(strcat(TRACK_AN(:,1),TRACK_AN(:,2),TRACK_AN(:,4),TRACK_AN(:,5)));
TRACK_AN = TRACK_AN(indTA,:);
有人可以帮忙吗?
答案 0 :(得分:3)
您可以使用unique
非常轻松地计算出这一点。关键是使用'rows'
标记作为unique
的第二个参数,这样您就可以找出矩阵的唯一行条目。我们只需要矩阵的第一,第二和第四列用于此过程,因此我们可以将这些列子集化。您还需要使用unique
的其他输出参数,以便我们可以确定原始单元格数组中唯一行的确切位置。这是算法下一部分所需的关键属性。
在第一次unique
来电中找到唯一的小组数组后,我们再应用unique
两次 - 一个用于c1
列,另一个用于c2
列1}}所以我们可以索引ID和年份。我们将使用unique
的第三个输出参数,以便我们可以将每列中的每个唯一编号分配给唯一ID。然后,我们使用accumarray
创建上面看到的最终矩阵,将第一列中的值作为行进行分箱,第二列作为此最终矩阵的列。换句话说:
%// Create cell array as per your example
C = {1 2006 20060425 559 'IA'
1 2007 20070129 559 'LO'
1 2007 20070826 559 'VC'
1 2008 20080825 34 'VP'
1 2009 20090116 34 'ZO'
4 2007 20070725 42 'OI'
4 2008 20080712 42 'TF'
4 2008 20080428 42 'XU'
11 2007 20070730 118 'AM'
11 2008 20080912 118 'HK'
11 2009 20090318 2 'VT'
11 2010 20100121 2 'ZZ'};
%// Get only those columns that are relevant
%// These are the first, second and fourth columns
Cmat = unique(cell2mat(C(:,[1 2 4])), 'rows');
%// Bin each of the first and second columns
%// Give them a unique ID per unique number
[~,~,ind] = unique(Cmat(:,1));
[~,~,ind2] = unique(Cmat(:,2));
%// Use accumarray to create your matrix
%// Edit - Thanks to Amro
%// Any values that are missing replace with NaN
finalMat = accumarray([ind ind2], Cmat(:,3), [], [], NaN);
输出是:
finalMat =
559 559 34 34 NaN
NaN 42 42 NaN NaN
NaN 118 118 2 2
我用NaN
替换了缺少的值来表示缺失值。
希望这有帮助!
答案 1 :(得分:3)
@ rayryeng的解决方案略有不同:
% data as cell array
C = {
1 2006 20060425 559 'IA'
1 2007 20070129 559 'LO'
1 2007 20070826 559 'VC'
1 2008 20080825 34 'VP'
1 2009 20090116 34 'ZO'
4 2007 20070725 42 'OI'
4 2008 20080712 42 'TF'
4 2008 20080428 42 'XU'
11 2007 20070730 118 'AM'
11 2008 20080912 118 'HK'
11 2009 20090318 2 'VT'
11 2010 20100121 2 'ZZ'
};
% we are only interested in three columns
CC = cell2mat(C(:,[1 2 4]));
% unique codes/years and their mapping
[codes,~,codesInd] = unique(CC(:,1));
[years,~,yearsInd] = unique(CC(:,2));
% pivot table
out = accumarray([codesInd yearsInd], CC(:,3), [], @max, NaN)
预期的结果:
>> out
out =
559 559 34 34 NaN
NaN 42 42 NaN NaN
NaN 118 118 2 2
或漂亮地打印成表格:
>> t = array2table(out, ...
'RowNames',cellstr(num2str(codes,'code_%d')), ...
'VariableNames',cellstr(num2str(years,'year_%d')));
>> t
t =
year_2006 year_2007 year_2008 year_2009 year_2010
_________ _________ _________ _________ _________
code_1 559 559 34 34 NaN
code_4 NaN 42 42 NaN NaN
code_11 NaN 118 118 2 2