Delete row based on criteria of 2 variables

7 Ansichten (letzte 30 Tage)
BenL
BenL am 13 Jan. 2017
Kommentiert: Adam am 14 Jan. 2017
In matrix A, I have n X 6 columns. In matrix B, I have n X 1 column. What I want to do is, if the element in column 6 of matrix A is larger than the element in column 1 of matrix B (i.e. A(:,6) > B(:,1)), then delete the row. Both matrices are of type double. What is the best way to script this?
I tried this:
for i = 1:n
if A(i, 6) > B(i, 1);
A(i,:) = [];
end
end
But it was quite slow (i have approx. 400,000 x 30 rows of data). Any other ways?
  3 Kommentare
Adam
Adam am 13 Jan. 2017
I would also expect this to do highly unwanted things. You should never delete elements from an array that you are looping round in a for loop because the indices will change so I would have expected this to crash with an index exceeds matrix dimensions at some point because your matrix is shrinking below n rows (unless you delete nothing) so when you get to the iteration of the for loop greater than the new size of your array it will crash with
Index exceeds matrix dimensions.
If you must delete things in a loop (in general programming, not here where the solutions below are far better) then always do it with a reverse iteration from back to front.
Roger Stafford
Roger Stafford am 13 Jan. 2017
Bearbeitet: Roger Stafford am 13 Jan. 2017
@BenL. As Adam has pointed out, your for-loop method will “do highly unwanted things.” Among these things is the fact that after a row has been deleted, since you do not delete the same row in matrix B, thereafter comparison of matching rows in A and B will be erroneous because the rows that previously had equal indices no longer do. Moreover, by erasing one row, if the next row was also to have been erased, that second row deletion will be skipped, because with its row position in A having been reduced by one, the for-loop would have to repeat its previous value i index value to accomplish the deletion, which of course it will not do. As Adam has pointed out, deleting elements in a vector one-at-a-time in a for-loop with increasing index value is a dangerous thing to do.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Adam
Adam am 13 Jan. 2017
A( A(:,6) > B, : ) = [];
  2 Kommentare
BenL
BenL am 14 Jan. 2017
This works so fast! I wonder what makes it so different?
Adam
Adam am 14 Jan. 2017
Vectorisation and indeing operations are what Matlab is good at and optimised for. For loops are not as bad as they are sometimes made out to be and have been in the past, but they are still nowhere near as fast as vectorisation in most (or all) cases.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Star Strider
Star Strider am 13 Jan. 2017
See if this does what you want:
N = 10;
A = randi(9, N, 6); % Create Data
B = randi(9, N, 1); % Create Data
Q = A; % Copy For Reference
A(A(:,6) > B,:) = []; % Desired Result

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by