Выполнение последовательности по группе - PullRequest
1 голос
/ 14 октября 2019

У меня есть матрица, содержащая групповые идентификаторы:

A = [ 1 ; 1 ; 2;2;2;3;3]

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

B = [ 1,1 ; 1,2 ; 2,1;2,2;2,3;3,1;3,2]

B =

 1     1
 1     2
 2     1
 2     2
 2     3
 3     1
 3     2

Какя могу сделать это без использования страшного цикла for? Спасибо!

Ответы [ 2 ]

4 голосов
/ 14 октября 2019

Входные данные содержат натуральные числа, не обязательно последовательные, но отсортированные

[B, ~] = find(sort(sparse(1:numel(A), A, true), 1, 'descend'));
B = [A B];

Это работает следующим образом:

  1. Создать промежуточную логическую разреженную матрицу с позициями столбцов, определяемыми A и последовательные позиции строк: sparse(1:numel(A), A, true). Хотя эта матрица может быть большой, создание ее как разреженной делает этот подход эффективным с точки зрения памяти.
  2. Переместите записи true в каждом столбце в верхнюю часть матрицы: sort(..., 1, , 'descend').
  3. Индексы строк содержат желаемый результат: [B, ~] = find(...).

Входные данные содержат положительные целые числа, не обязательно последовательные, не обязательно отсортированные

t = sparse(1:numel(A), A, true);
t = t.*cumsum(t, 1);
B = [A nonzeros(t.')];

Это работаетследующим образом:

  1. Создайте промежуточную логическую разреженную матрицу, как и раньше.
  2. В каждом столбце заменяйте ненулевые значения на последовательные значения 1, 2, ...
  3. Транспонировать матрицу. Ненули в линейном порядке являются желаемым результатом.
0 голосов
/ 14 октября 2019

Это работает для нецелых.

[s, is] = sort(A)
[~, d] = cummax(s) ;
C(is, :) = (2:numel(A) + 1).'  -  d;
B = [A C] ;

Если вход отсортирован:

[~, d] = cummax(A) ;
C = (2:numel(A) + 1).'  -  d;
B = [A C] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...