Detect where an array becomes negative
64 次查看(过去 30 天)
显示 更早的评论
Hi everyone,
I have an array of size 401 x 381 which has positive and negative values. I would like to detect which row in each column this change of sign occurs for the purposes of comparison. If anyone has any ideas they will be appreciated. If you need to see the full code then just ask, I thought I would leave it out for the sake of simplicity.
Thanks, John.
6 个评论
dpb
2016-7-26
编辑:dpb
2016-7-26
Then for the latter columns there isn't a transition from + to -, it's t'other way 'round. So you're actually looking for the sign transition. Is zero a possible element in the array, too? What is the result in that column if so? Posted a solution that will give the zero location in that case.
回答(2 个)
dpb
2016-7-25
编辑:dpb
2016-7-26
Sometimes it's just as easy to loop...it's unfortunate in cases like this find isn't vectorized; a cleaner syntax doesn't pop into mind at the moment altho I suspect there is something I'm just not seeing at the moment...
nc=size(x,2); % number of columns
ix=zeros(1,nc); % preallocate for the index
for i=1:nc
ix(i)=find(x(:,i)<0,1); % the first negative location in ith column
end
ADDENDUM As Per notes, the above presumes there is a valid entry in every column, if it's possible that's not so then include test that the result from find isn't empty...
for i=1:nc
idx=find(x(:,i)<0,1); % the first negative location in ith column
if ~isempty(idx) % if none, find returns empty array
ix(i)=idx; % save the valid ones...
end
end
As a design note, I chose the above so the resulting vector would have same length as number of columns in original array consistent with other Matlab behavior of things that operate over columns/rows. Since indices are always one-based, zero is unique indicator of missing value; one could also use NaN as the initial value as well for more obvious flag.
ADDENDUM 2
With the addition of the other conditional, the above works with a slight modification --
nc=size(x,2); % number of columns
ix=zeros(1,nc); % preallocate for the index
for i=1:nc
ix(i)=find([0;diff(sign(m(:,i)))],1);
end
With the caveat that, as described, there will be a sign change in each column so the empty condition doesn't occur...the defensive strategem has already been demonstrated above just in case.
ERRATUM I just note I left out the subscripting expression on the x array initially; what one gets for "keyboard debugging" instead of cut 'n paste. Fixed all instances I believe...if missed one, should be apparent.
0 个评论
Star Strider
2016-7-25
编辑:Star Strider
2016-7-25
This one approach:
[r,c] = find(A < 0);
Uc = unique(c);
R = {Uc accumarray(c, r, [], @(c) {r(c)})};
celldisp(R)
It produces ‘R’, a cell with the first column being the column numbers and the other cells being the corresponding rows with the negative values.
EDIT — Note that this outputs only columns with at least one negative number (my reason for using the unique function). A column with no negative number does not appear.
2 个评论
Star Strider
2016-7-26
I’m not certain what you mean by ‘linear indexed’. See if this does what you want:
A = randi([-9 9], 5, 6); % Create Data
[r,c] = find(A < 0);
R = {[1:size(A,2)]' accumarray(c, r, [], @(c) {r(c)})};
for k1 = 1:size(A,2)
Rk(k1,:) = R{2}{k1}(1);
end
Result = [R{1} Rk]'
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!