フィルターのクリア

Change a value after a maximum five-consecutive column of zero

2 ビュー (過去 30 日間)
Jalu Naradi
Jalu Naradi 2018 年 5 月 9 日
コメント済み: Jalu Naradi 2018 年 5 月 15 日
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,
  3 件のコメント
Jalu Naradi
Jalu Naradi 2018 年 5 月 9 日
Sorry, it was my mistake. I edit the example so that there are 6 consecutive zeros now before 1
Jalu Naradi
Jalu Naradi 2018 年 5 月 10 日
@Jan, the matrix size is [3000,1000]. Thank you

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

採用された回答

Guillaume
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
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).
Jalu Naradi
Jalu Naradi 2018 年 5 月 15 日
Thank you for your explanation

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

その他の回答 (2 件)

Jan
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
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
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.
Jalu Naradi
Jalu Naradi 2018 年 5 月 10 日
Thank you Ameer for your answer. As Guillaume mentioned above, there are several patterns that acceptable here.

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

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by