首页 > 解决方案 > 如何排除数组中数据块中的重复元素?

问题描述

我有一个包含以下数据数组的文件

7
1  2  3  120.12
4  5  8   70.25
6 11 12  111.20
2  6 10   90.39
3  2  1  120.12
10 6  2   90.39
11 2  3   87.12 
9
1  2  3  110.12
4  5  8   70.25
6 11 12  111.20
2  6 10   60.39
3  2  1  110.12
10 6  2   60.39
11 2  3   87.12
20 1  9  156.48
3  2 11   87.12 
...

文件由数十个数据块组成。每个数据块有一个顶部标题行(数据行数 = 数据块大小),数据段有 4 列。这 4 列是 3 个点的角度。前三列是点编号或点索引。第 4 列是 3 个点的角度。所以,它是“ID1 ID2 ID3 角度”。例如,“1 2 3 120.12”表示 1-2-3 的角度(本例中顶点为 '2')为 120.12 度。

问题是,有重复的元素。在第一帧中,有 2 个重复对:1 2 3 和 3 2 1,以及 2 6 10 和 10 6 2。在第二帧中,有 3 个重复项,1 2 3 和 3 2 1,以及 2 6 10 和10 6 2 和 11 2 3 和 3 2 11。所有这些对的角度相同,但方向相反。

如何排除那些重复元素并为每个数据块只保留一个?我希望上面的例子变成这样:

5
1  2  3  120.12
4  5  8   70.25
6 11 12  111.20
2  6 10   90.39
11 2  3   87.12 
6
1  2  3  110.12
4  5  8   70.25
6 11 12  111.20
2  6 10   60.39
11 2  3   87.12
20 1  9  156.48
...

我希望获得每个数据块和所有角度的角度分布和 normalPDF,而不管角度如何。但我不确定如何排除那些重复的组合。

不同的组合“幸运地”发生相同角度的可能性很小,所以我试图排除基于 ID 号的重复元素,例如 ID1 ID2 ID3 重复 ID3 ID2 ID1。但我找不到任何适合 if-loop 和 for-loop 或函数的逻辑......

标签: arraysmatlabdataframe

解决方案


这是一个经典的工作accumarray。由于您没有提供任何加载数据的代码,我只是用readmatrix. 如果您以另一种方式加载代码,您可能需要调整代码。

% given
DATA = readmatrix('data.txt','NumHeaderLines',0);      % load data
DATA(:,end) = [];                                      % remove last column, as only NaN

hl = any(isnan(DATA(:,2:end)),2);                      % identify header lines
subs = cumsum(hl);                                     % indices for accumarray

% unqiue rows of chunks of data
y = accumarray(subs(:), ...                            % indices of chunks
               1:numel(subs).', ...                    % numbering of rows
               [], ...                                 % not used
               @(x) { ...                              % anonymous function
               unique( ...                             % unique 'rows' of chunks
               [sort( DATA(x,1:3), 2) DATA(x,4)], ...  % first 3 columns sorted
               'rows', 'stable' ...                    % stable -> do not change order
               )});
y = cell2mat(y);                                       % tranfsform back to array

y =

    7.0000       NaN       NaN       NaN
    1.0000    2.0000    3.0000  120.1200
    4.0000    5.0000    8.0000   70.2500
    6.0000   11.0000   12.0000  111.2000
    2.0000    6.0000   10.0000   90.3900
    2.0000    3.0000   11.0000   87.1200
    9.0000       NaN       NaN       NaN
    1.0000    2.0000    3.0000  110.1200
    4.0000    5.0000    8.0000   70.2500
    6.0000   11.0000   12.0000  111.2000
    2.0000    6.0000   10.0000   60.3900
    2.0000    3.0000   11.0000   87.1200
    1.0000    9.0000   20.0000  156.4800

推荐阅读