figure title matlab
Crear un vector de índice basado en los valores de inicio y detención (2)
Aquí hay una colección de métodos:
Método 1 de https://stackoverflow.com/a/39422485/6579744 :
lo = A(:,1);
up=A(:,2);
index=cumsum(accumarray(cumsum([1;up(:)-lo(:)+1]),[lo(:);0]-[0;up(:)]-1)+1);
index= index(1:end-1);
Método 2: esto es de https://stackoverflow.com/a/38507276/6579744 . También proporcioné la misma respuesta, pero debido a que la respuesta de Divakar es anterior a la mía, prefirió su respuesta (modificada):
start_idx = A(:,1)'';
end_idx = A(:,2)'';
lens = end_idx - start_idx + 1;
shift_idx = cumsum(lens(1:end-1))+1;
id_arr = ones(1,sum(lens));
id_arr([1 shift_idx]) = [start_idx(1) start_idx(2:end) - end_idx(1:end-1)];
index = cumsum(id_arr);
Método 3: esto es mío
N = A(:,2) - A(:,1) +1;
s=cumsum([ 1; N]);
index=(1:s(end)-1) -repelem(s(1:end-1),N) + repelem(A(:,1),N);
%octave index=(1:s(end)-1) -repelems(s(1:end-1),[1:numel(N);N'']) + repelems(A(:,1),[1:numel(N);N'']);
Método 4 : otro usuario de este hilo por thewaywewalk
A = A.'';
idx = bsxfun(@plus, A, [0; 1]);
A = A(:);
dA = diff(A); dA(1:2:end) = 0;
idx = idx(~( [0;dA] == 1 | [dA;0] == 1 ));
mask = zeros(max(A),1);
mask(idx(:)) = (-1).^(0:numel(idx)-1);
index = find(cumsum(mask));
Método 5 su segundo método:
index = cell2mat(arrayfun(@(n) A(n, 1):A(n, 2), 1:size(A, 1), ''uni'', 0));
Método 6 desde https://stackoverflow.com/a/39423102/6579744 :
sz= size(A, 1);
index_c = cell(1,sz);
for n = 1:sz
index_c{n} = [A(n, 1):A(n, 2)];
end
index = cell2mat(index_c);
El Método 7 solo funciona en Octave:
idx = 1:size(A ,1);
index_a =bsxfun(@(a,b) (a(b):A (b,2))'',A (:,1),idx);
index = index_a(index_a ~= 0);
Método 8 su primer método:
index = [];
for n = 1:size(A, 1)
index = [index A(n, 1):A(n, 2)];
end
Datos de prueba:
i= 1:500:10000000;
j= i+randi([1 490],1, numel(i));
A = [i'', j''];
El resultado probado en Octave, en Matlab puede ser diferente
method1: 0.077063 seconds
method2: 0.094579 seconds
method3: 0.145004 seconds
method4: 0.180826 seconds
method5: 0.317095 seconds
method6: 0.339425 seconds
method7: 3.242287 seconds
method8: doesn''t complete in 15 seconds
Esta pregunta ya tiene una respuesta aquí:
Basado en una matriz que contiene varias filas del comienzo (primera columna) y el final (segunda columna) de un intervalo de índice, me gustaría crear un vector de todo el índice. Por ejemplo, si A = [2 4; 8 11 ; 12 16]
A = [2 4; 8 11 ; 12 16]
A = [2 4; 8 11 ; 12 16]
, me gustaría tener el siguiente index = [2 3 4 8 9 10 11 12 13 14 15 16]
vectorial index = [2 3 4 8 9 10 11 12 13 14 15 16]
.
Estoy buscando la forma más rápida de hacerlo. Por ahora, encontré solo dos posibilidades:
1) con un bucle
index = [];
for n = 1:size(A, 1)
index = [index A(n, 1):A(n, 2)];
end
2) con arrayfun
index = cell2mat(arrayfun(@(n) A(n, 1):A(n, 2), 1:size(A, 1), ''uni'', 0));
Curiosamente, arrayfun
es mucho más rápido que la versión de bucle, y no sé por qué. Además, uso una conversión de celda a alfombra, así que eso es extraño. ¿Qué piensas sobre eso? ¿Tienes otras sugerencias?
Gracias por tu ayuda
Difícil decir qué tan rápido es eso, al menos no hay bucle:
A = [1,3;11,13;31,33;41,42;51,54;55,57;71,72];
%// prepare A
A = A.'';
%// create index matrix
idx = bsxfun(@plus, A, [0; 1]);
%// special case: 54 and 55 are basically superfluous
%// need to be removed, but 71 and 72 shouldn''t
A = A(:);
dA = diff(A); dA(1:2:end) = 0;
idx = idx(~( [0;dA] == 1 | [dA;0] == 1 ));
%// create mask
mask = zeros(max(A),1);
mask(idx(:)) = (-1).^(0:numel(idx)-1);
%// index vector
out = find(cumsum(mask))
out.'' =
1 2 3 11 12 13 31 32 33 41 42 51 52 53 54 55 56 57 71 72