overwriting certain lines in a matrix with previous lines that satisfy a condition.

1 visualización (últimos 30 días)
I have a vector which marks rows that needs to be overwritten in a matrix.
The marked rows should be replaced with the previously row that isn't marked.
Line 1 will never be marked so no need to take account for the potential error.
The matrix is big and will always have enough rows that markedrows refers to.
Vector: markedrows = [3,6,7,14,15,16,17] (markedrows will always be in ascending order)
So the deal is, according to markedrows, in the matrix:
  • The new line 3 should be the same as line 2
  • The new line 6 should be the same as line 5
  • The new line 7, however, shouldn't be line 6 cause line 6 is marked too, it should instead be line 5.
Following this pattern would make line 14, 15, 16 and 17 all turn into line 13.
I hope this makes sence and that you can help :).

Respuesta aceptada

Guillaume el 18 de Nov. de 2014
Simply do:
for row = markedrows
m(row, :) = m(row-1, :);
row 14 is replaced by row 13, row 15 by row 14 which is now equal to row 13, etc.
  8 comentarios
Søren el 18 de Nov. de 2014
I must have done a typo the first time I ran it then, it works perfectly now.
Thanks alot to both of you, you've been very helpful!

Iniciar sesión para comentar.

Más respuestas (2)

Kelly Kearney
Kelly Kearney el 18 de Nov. de 2014
marked = [3,6,7,14,15,16,17];
good = setdiff(1:20, marked);
prev = arrayfun(@(x) good(find(good < x,1,'last')), marked)
prev =
2 5 5 13 13 13 13
  3 comentarios
Kelly Kearney
Kelly Kearney el 18 de Nov. de 2014
Guillaume's method is more efficient if you just need to replace the rows and be done with it, but if you want a record of which rows were replaced with which, this is an alternative.
And just run
m(marked,:) = m(prev,:);
to do the actual replacement.

Iniciar sesión para comentar.

Andrew Reibold
Andrew Reibold el 18 de Nov. de 2014
Editada: Andrew Reibold el 18 de Nov. de 2014
This is not the most efficient memory-wise, but it is a working solution and I tried to use basic commands. I just made up a matrix m to demonstrate. See the comment for change that will let you increment the other direction if you want.
m = round(rand(2,20)'*10) %a random matrix of numbers 1-10
markedrows = [3,6,7,14,15,16,17];
new_m = m;
for row = 1:size(m,1)
nrow = row;
while find(markedrows == nrow);
nrow = nrow-1; %make this MINUS a PLUS to swap direction.
new_m(row,:) = m(nrow,:);
new_m %outputs to command window for comparison
  5 comentarios
Andrew Reibold
Andrew Reibold el 18 de Nov. de 2014
Editada: Andrew Reibold el 18 de Nov. de 2014
Short answer - Yes, there are better solutions. :D
For now, go check Guillaumes solution again. I actually think his solution is superior in many ways now that I correctly realize what it is doing.
It would be WAY better for large matrices because it only spends time where necessary.

Iniciar sesión para comentar.


Más información sobre Matrix Indexing en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by