MATLAB - 在列中查找重复值并从该行中提取值

时间:2015-06-02 02:14:54

标签: matlab matrix

我在第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。请指教。

2 个答案:

答案 0 :(得分:3)

您可以使用cell-arrays来解决这类问题。当所有列或所有行的长度不相等时,使用单元格数组。每行/每列可以具有不同的大小。他们不需要填充来使它们的大小相等。

使用accumarray

的一种方法
[~,~,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之后):

使用bsxfuncellfun

的方法
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