我在第1列中有一个重复值的矩阵,例如:
A = [
1 34 463;
2 45 684;
2 23 352;
3 31 256;
1 46 742;
4 25 234]
使用A
,我希望从第2列中为第1列中的每个值提取数据,以输出B
。如果第1列中的值发生重复,则第2列中的相应值将放入附加输出列(可以在不发生重复的情况下使用NaN)。例如:
B = [
1 34 46;
2 45 23;
3 31 NaN;
4 25 NaN]
(B
中的第一列不是必需的,但此处包括在内以供澄清)
我试图使用find函数,if
语句和循环的组合,但没有成功。理想情况下,成功的方法也是有效的,因为实际数据集很大。
我使用版本R2012a。请指教。
答案 0 :(得分:3)
您可以使用cell-arrays
来解决这类问题。当所有列或所有行的长度不相等时,使用单元格数组。每行/每列可以具有不同的大小。他们不需要填充来使它们的大小相等。
[~,~,idx] = unique(A(:,1));
outC = accumarray(idx,A(:,2),[],@(x) {x.'}) %//'
%// If you want the outputs in sorted order use the following code instead
%// outC = accumarray(idx,A(:,2),[],@(x) {sort(x).'})
outC =
[1x2 double]
[1x2 double]
[ 31]
[ 25]
您可以使用类似outC{1}
>> outC{1}
ans =
46 34
如果您想一次查看整个矩阵,可以使用celldisp
函数
>> celldisp(outC)
outC{1} =
46 34
outC{2} =
23 45
outC{3} =
31
outC{4} =
25
如果你希望输出为NaN
填充矩阵而不是单元格数组,你可以这样做(在你上面获得outC
之后):
lens = cellfun(@numel,outC);
maxSize = max(lens);
out = nan(maxSize,numel(outC));
mask = bsxfun(@le,(1:maxSize).',lens(:).')
out(mask) = horzcat(outC{:});
out = out.'
<强>输出:强>
out =
46 34
23 45
31 NaN
25 NaN
如果您使用替代方法(输出排序)来查找outC
,结果将是:
out =
34 46
23 45
31 NaN
25 NaN
答案 1 :(得分:3)
这将是一种方法 -
[~,~,idx] = unique(A(:,1),'stable') %// Find IDs for each element from col-1
[~,sorted_idx] = sort(idx) %// Get sorted IDs
grp_vals = A(sorted_idx,2) %// Get second column elements grouped together
grp_lens = accumarray(idx,1)%// Find Group lengths
%// Create a mask for a 2D array where the ones are places where grouped
%// elements are to be put.
mask = bsxfun(@le,[1:max(grp_lens)]',grp_lens(:).')
%// Create a nan filled array of same shape as mask and finally fill masked
%// places with grouped elements. Transpose at the end to get desired output.
out = nan(size(mask))
out(mask) = grp_vals
out = out.'
示例运行 -
>> A,out
A =
1 34 463
2 45 684
0 23 352
-3 31 256
1 46 742
4 25 234
1 12 99
-3 -20 56
out =
34 46 12
45 NaN NaN
23 NaN NaN
31 -20 NaN
25 NaN NaN