필터 지우기
필터 지우기

Delete row if element is out of specified range

조회 수: 14 (최근 30일)
JZ
JZ 2015년 12월 18일
편집: Jan 2015년 12월 20일
I have the following:
min = 67;
max = 69;
nmat =
0 0.9000 1.0000 64.0000 82.0000 0 0.5510
1.0000 0.9000 1.0000 71.0000 89.0000 0.6122 0.5510
2.0000 0.4500 1.0000 71.0000 82.0000 1.2245 0.2755
2.5000 0.4500 1.0000 69.0000 70.0000 1.5306 0.2755
3.0000 0.4528 1.0000 67.0000 72.0000 1.8367 0.2772
3.5000 0.4528 1.0000 66.0000 72.0000 2.1429 0.2772
4.0000 0.9000 1.0000 64.0000 70.0000 2.4490 0.5510
5.0000 0.9000 1.0000 66.0000 79.0000 3.0612 0.5510
6.0000 0.9000 1.0000 67.0000 85.0000 3.6735 0.5510
7.0000 1.7500 1.0000 66.0000 72.0000 4.2857 1.0714
9.0000 0.4528 1.0000 64.0000 74.0000 5.5102 0.2772
9.5000 0.4528 1.0000 67.0000 81.0000 5.8163 0.2772
10.0000 0.9000 1.0000 71.0000 83.0000 6.1224 0.5510
11.0000 0.4528 1.0000 71.0000 78.0000 6.7347 0.2772
11.5000 0.4528 1.0000 69.0000 73.0000 7.0408 0.2772
12.0000 0.4528 1.0000 67.0000 71.0000 7.3469 0.2772
12.5000 0.4528 1.0000 66.0000 69.0000 7.6531 0.2772
13.0000 0.4528 1.0000 67.0000 83.0000 7.9592 0.2772
13.5000 0.4528 1.0000 66.0000 72.0000 8.2653 0.2772
14.0000 0.4528 1.0000 64.0000 74.0000 8.5714 0.2772
14.5000 0.4528 1.0000 63.0000 70.0000 8.8776 0.2772
15.0000 0.9000 1.0000 64.0000 82.0000 9.1837 0.5510
16.0000 1.8028 1.0000 64.0000 75.0000 9.7959 1.1037
and I would like to delete any row in which the value for (i,4) is out of the particular range:
min < nmat(i,4) < max
I am aware that Matlab does not like the syntax a < b < c, but I have tried several variations of code and cannot understand where my error is.
min = 67;
max = 69;
for i=1:length(nmat)
if (nmat(i,4) < min) || (nmat(i,4) > max)
nmat(i, :) = [];
end
end
Logical operations aside, I cannot even get the loop to properly perform the more simple task of deleting rows with an (i,4) value below the min:
min = 67;
max = 69;
for i=1:length(nmat)
if nmat(i,4) < min
nmat(i, :) = [];
end
end
Any help is much appreciated.

답변 (3개)

Jan
Jan 2015년 12월 18일
편집: Jan 2015년 12월 20일
toDelete = ((min < nmat(:,4)) | (nmat(:,4) < max));
nmat(toDelete, :) = [];
Your loop must fail, because it checks all rows of teh matrix, but this matrix shrinks during the processing. The limits of the loop are determined once only at the beginning.
Alternatively you could run the loop from size(nmat, 1) backward to 1. But the iterative changing of the array size wastes resources, so better avoid this.
  댓글 수: 1
JZ
JZ 2015년 12월 18일
Jan, why am I getting the following error with your code?
Subscript indices must either be real positive integers or logicals.

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


Guillaume
Guillaume 2015년 12월 18일
First a comment on your code:
for i = 1:length(nmat)
In my opinion, length should be removed from matlab. There are clearer alternatives and most people who use it don't understand how it works.
With a 2d matrix, length is the size of the largest dimension. So if the matrix has more rows than columns, it's the number of rows and if the matrix has more columns than rows, it's the number of columns.
In your particular case, length might start as the number of columns, but once you've deleted enough will switch the number of columns!
It's better to always be explicit. If you want the number of elements in a vector use numel, if you want the number of rows in a matrix use size(m, 1), and size(m, 2) to get the number of columns.
Second comment: Do not use min and max as variable names as you won't be able to use the min and max function of matlab.
Now, to answer your question, the simplest way to delete your rows is with:
thresholdmin = 67;
thresholdmax = 69;
nmat(nmat(:, 4) < thresholdmin | nmat(:, 4) > thresholdmax, :) = []
  댓글 수: 3
Guillaume
Guillaume 2015년 12월 18일
First, your expression does not work for two reasons, a) you've got the wrong column (2 instead of 1) and b) you've fallen foul of operator precedence. In matlab AND always takes precedence over OR, so your expression says:
(less than 70 in column 4 AND less than 1 in column 2) OR (greater than 3 in column 2)
The answer is to use parentheses just as you'd written in your statement, so:
nmat(nmat(:, 2) < col4min & (nmat(:, 1) < col2min | nmat(:, 1) > col2max), :) = []
The way this works, nmat(:, x) is a column vector with as many rows as nmat. Compared to a scalar you get a column vector of logicals. This is then combined with other column vectors of logicals with & or |, so in the end you have a column vector to select with row you want to pick / discard. To delete a whole row, you need to select all the columns, hence why you have : for the columns. In short, you're simply using
nmat(rowidx, colidx) = []
where rowidx is a logical vector to select which rows you want, and colidx is : to select all columns.
JZ
JZ 2015년 12월 18일
Thanks for all the explanations - It seems I have it working now.

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


Stalin Samuel
Stalin Samuel 2015년 12월 18일
min = 67;
max = 69;
nmat = randi([1 500],100,100);%for example
[row,col] = find(nmat>min&nmat<max)
nmat(unique(row),:)=[]

카테고리

Help CenterFile Exchange에서 Programming에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by