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
  1 件のコメント
BenL
BenL 2017 年 1 月 14 日
Great!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by