Problem with for loop
1 次查看(过去 30 天)
显示 更早的评论
Hallo,
I have a large matrix let's say A 150 * 220000 , including columns that are set entirely to zero .
I want to find '' column wise'' the first element that is larger than 5 and the first element smaller than 200 and store them as two vectors
I creat a for loop, but it breaks when it reaches the first zero column in the matrix. so instead of idx_start 1 * 220000 , I get idx_start 1 * 15000
how can i modify my code so the loop continue over the zero columns?
and would be better if I replaced the zero columns with NaN?
I tried something with isempty but it does not work like I want.
wenn the condition is not met, it is enough to be replaced with NaN
[nx,ny] = size(A) ;
for j = 1:ny
idx_start(:,j) = find(A(:,j)> 5 ,1,'first') ;
if (isempty(A(:,j)))
continue
idx_end(:,j) = find (A(:,j) < 200 , 1, 'first');
end
end
4 个评论
Jan
2018-11-23
isempty(A(:,j)) is always false, because it checks the number of elements, not the contents of the elements. See any().
采纳的回答
Andrei Bobrov
2018-11-23
编辑:Andrei Bobrov
2018-11-23
s = size(A,2);
[ii,jj] = find(cumsum(cat(3,A > 5,A < 200)) == 1);
out = accumarray([rem(jj-1,s)+1,ceil(jj/s)],ii,[s,2],[],nan);
更多回答(2 个)
Dennis
2018-11-23
The problem is that find might return an empty vector and in that case the assignment fails.
You could catch this error by checking if there are any values > 5.
if any(A(:,j)>5)
idx_start(:,j) = find(A(:,j)> 5 ,1,'first') ;
else
idx_start(:,j)=0 %or NaN or whatever you want to happen
end
I would prefer the use of only one array to store start and end values. Especially since you are always only storing 1 value you could do it like this:
if any(A(:,j)>5) && any(A(:,j)<200)
idx(1,j) = find(A(:,j)> 5 ,1,'first');
idx(2,j) = find (A(:,j) < 200 , 1, 'first');
else
idx(1,j)=0; %or NaN or whatever you want to happen
idx(2,j)=0; %or NaN or whatever you want to happen
end
Jan
2018-11-23
编辑:Jan
2018-11-23
In for j=1:nx you run a loop over the rows, not columns. Do you mean ny here?
[nx, ny] = size(A);
idx_start = NaN(1, nx); % Pre-allocate!!!
idx_end = NaN(1, nx); % Pre-allocate!!!
for j = 1:ny % Or really nx?
m = find(A(:, j) > 5, 1, 'first');
if ~isempty(m)
idx_start(j) = m;
end
m = find(A(:, j) < 200, 1, 'first');
if ~isempty(m)
idx_end(j) = m;
end
end
Now all elements of the idx_... vectors are NaN, if the corresponding column of A does not contain matching elements. You can skip the search also, if the column contains zeros only:
for j = 1:ny % Or really nx?
col = A(:, j);
if any(col) % Skip if column contains zeros only
m = find(col > 5, 1, 'first');
if ~isempty(m)
idx_start(j) = m;
end
m = find(col < 200, 1, 'first');
if ~isempty(m)
idx_end(j) = m;
end
end
end
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Characters and Strings 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!