Change a value after a maximum five-consecutive column of zero
2 次查看(过去 30 天)
显示 更早的评论
I have a matrix [3000,1000] which has only 0, 1, and -1. If there is a -1 in a row followed by a (maximum) consecutive five-columns of zeros then followed by 1, this 1 value should change to 2.
I am looking for the fastest way to do it in Matlab. Is there anyway without a loop? if not, what is the best way?
For example
A = [1 0 0 -1 0 0 0 0 1 0 0 -1 0 0 1;
0 -1 0 0 0 0 0 0 1 -1 0 1 0 0 -1];
% I would like to change matrix A as follow
A = [1 0 0 -1 0 0 0 0 2 0 0 -1 0 0 2;
0 -1 0 0 0 0 0 0 1 -1 0 2 0 0 -1 ];
Thanks in advance,
采纳的回答
Guillaume
2018-5-9
I don't think this can be done more efficiently than with a loop over the rows:
for row = 1:size(A, 1)
col = find(A(row, :));
tochange = diff(col) <= 5 & A(row, col(1:end-1)) == -1 & A(row, col(2:end)) == 1;
A(row, col([false, tochange])) = 2;
end
4 个评论
Guillaume
2018-5-14
The result of diff is a vector with one less element than col. tochange(1) actually corresponds to col(2|, so I just prepend false to vector (since the 1st element is never going to have to be changed anyway).
更多回答(2 个)
Jan
2018-5-9
编辑:Jan
2018-5-9
A = [1 0 0 -1 0 0 0 0 1 0 0 -1 0 0 1; ...
0 -1 0 0 0 0 0 1 -1 0 1 0 0 1 0];
[s1, s2] = size(A);
Av = reshape(A.', 1, []); % Convert it to 1 vector
for k = 0:5
index = strfind(Av, [-1, zeros(1, k), 1]);
index = index(mod(index, s2) < s2 - k); % Omit matches at end of row
Av(index + k + 1) = 2;
end
B = reshape(Av, s2, []).';
Ameer Hamza
2018-5-9
This is an approach to modify an identify an arbitrary pattern and modify a value, Using for loop and comparing them by converting them to char array.
A = [1 0 0 -1 0 0 0 0 1 0 0 -1 0 0 1;
0 -1 0 0 0 0 0 1 -1 0 1 0 0 1 0];
pattern = [-1 0 0 0 0 1];
strA = num2str(A+1); % +1 is added to remove negative signs for easy manipulation as strings
strPattern = strrep(num2str(pattern+1), ' ', '');
for i=1:size(A,1)
index = strfind( strrep(strA(i,:), ' ', ''), strPattern) + length(pattern) -1;
if ~isempty(index)
A(i, index) = 2;
end
end
2 个评论
Guillaume
2018-5-9
Note that you don't need to convert numbers to char to use strfind. Despite not being actually documented, strfind works just as well for detecting patterns of numbers
strfind(A(i, :), [-1 0 0 0 0 0 1])
The problem here is that several patterns are acceptable, [-1 1], [-1 0 1], ..., [-1 0 0 0 0 0 1], so a pattern search is not particularly useful. I guess a regexp would work (which does requires a conversion to char) but I'm not convinced the extra complexity and time taken by the regex would be better than the simple for loop I've detailed.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!