Delete row based on criteria of 2 variables

조회 수: 7 (최근 30일)
BenL
BenL 2017년 1월 13일
댓글: Adam 2017년 1월 14일
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
Adam
Adam 2017년 1월 13일
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 2017년 1월 13일
편집: Roger Stafford 2017년 1월 13일
@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.

댓글을 달려면 로그인하십시오.

채택된 답변

Adam
Adam 2017년 1월 13일
A( A(:,6) > B, : ) = [];
  댓글 수: 2
BenL
BenL 2017년 1월 14일
This works so fast! I wonder what makes it so different?
Adam
Adam 2017년 1월 14일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Star Strider
Star Strider 2017년 1월 13일
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

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by