MATLAB Answers

Delete row based on criteria of 2 variables

22 views (last 30 days)
BenL
BenL on 13 Jan 2017
Commented: Adam on 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 Comments

Star Strider
Star Strider on 13 Jan 2017
It’s slow because the for loop is slow.
Logical indexing, with an implied and much more efficient loop, is much faster.
Adam
Adam on 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 on 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.

Sign in to comment.

Accepted Answer

Adam
Adam on 13 Jan 2017
A( A(:,6) > B, : ) = [];

  2 Comments

BenL
BenL on 14 Jan 2017
This works so fast! I wonder what makes it so different?
Adam
Adam on 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.

Sign in to comment.

More Answers (1)

Star Strider
Star Strider on 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