Как я могу исключить повторяющиеся элементы в кусках данных в массиве? - PullRequest
1 голос
/ 21 апреля 2020

У меня есть файл со следующим массивом данных

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. Все эти пары имеют одинаковый угол, но только противоположное направление.

Как я могу исключить эти повторяющиеся элементы и оставить только один для каждого блока данных? Я sh приведенный выше пример должен выглядеть следующим образом:

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
...

I w * sh, чтобы получить распределение и нормальный PDF угла для каждого блока данных и для всех углов независимо от углов. Но я не уверен, как я могу исключить эти повторяющиеся комбинации.

Небольшие шансы на то, что один и тот же угол «к счастью» возникают в разных комбо, поэтому я пытался исключить повторяющиеся элементы на основе идентификационных номеров, например, ID1 ID2 ID3 повторяется с помощью ID3 ID2 ID1. Но я не смог найти подходящую логику c для if-l oop и for-l oop или для функции ...

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Допустим, вы разделили свои блоки, и один из блоков сохраняется в виде двойного массива n-на-4 block.

. Вам нужно отсортировать вершины в каждой строке, сохраняя при этом 2-й фиксированный. Этого можно достичь, используя sort вдоль измерения строки следующим образом

sort([block(:,1),block(:,3)],2);

Второй вход 2 определяет сортировку всех строк вдоль столбца.

Далее необходимо добавить обратно 2-х вершин и выбрать уникальные комбинации вершин.

unique([block(:,2),sort([block(:,1),block(:,3)],2)],'row');

'row' означает выбрать уникальные строки в целом, а не уникальные отдельные элементы. Вы можете добавить 'stable', чтобы сохранить существующий порядок. Но вы не указали такую ​​необходимость в вопросе. Поэтому я оставлю это необязательным.

Чтобы получить исходный порядок вершин, мы используем индексы уникальных строк следующим образом. Здесь необходимо убедиться, что повторяющиеся углы, идентифицированные действительной последовательностью вершин, имеют одинаковое значение угла. (В противном случае вам нужно добавить block(:,4) к приведенной выше формуле.)

[~, ind] = unique([block(:,2),sort([block(:,1),block(:,3)],2)],'row');

И ваш окончательный ответ: (только две строки ниже)

[~, ind] = unique([block(:,2),sort([block(:,1),block(:,3)],2)],'row');
block(ind,:),
ans =
    1.0000    2.0000    3.0000  120.1200
   11.0000    2.0000    3.0000   87.1200
    4.0000    5.0000    8.0000   70.2500
    2.0000    6.0000   10.0000   90.3900
    6.0000   11.0000   12.0000  111.2000

Если бы кто-то мог написать ответ на основе oop на основе ручного кэширования, мне было бы любопытно увидеть, как это происходит выше, и циклическое с ручным кэшированием, которое быстрее.

1 голос
/ 21 апреля 2020

Это классическая c работа для 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...