A doubt regarding a simple For loop indexing for certain rows only.

2 ビュー (過去 30 日間)
abhisrisai
abhisrisai 2019 年 8 月 2 日
コメント済み: abhisrisai 2019 年 8 月 2 日
Hi,
I have a matrix 'a' and I want to index only certain rows and delete them. Refer to code below.
Logic : when I reach the row starting point A or starting point B, I want to delete the following rows which contain the value [1 2 4 5]. I need to delete only those which come below either starting point A or B, also, the number of times [1 2 4 5] repeat is not fixed. If you observe, even after the 11th row [1 2 3 7] there are values [1 2 4 5] present but I want to retain them.
Any suggestions would be of great help, thank you. :)
a = 1 2 3 4 % start point A
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 6 % start point B
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 7 % don't delete anything from below here.
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5
b = size(a,1);
for c = 1:b
if a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
for d = c+1:b
if (a(d, [1:4]) == [1, 2, 4, 5])
a(d, 5) = 1;
end
end
end
end
% displaying the numbers except for the ones that have 1 in their last column, basically deleting the rows with 1 in their last column
z = a(:, end);
y = a(~(z == 2), :);
y(:, end) = []
%% The result I'm obtaining from the above code :
y = 1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 5
1 2 3 7
1 2 3 5
%% My expected output :
y = 1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 5
1 2 3 7
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5

採用された回答

Guillaume
Guillaume 2019 年 8 月 2 日
編集済み: Guillaume 2019 年 8 月 2 日
Since nobody has explained why your code doesn't work:
There are several problems with your
if a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
First one is that your condition is a row vector and in all likelyhood you don't know how if behaves when the condition is a vector and not a scalar. That is the result of
a(c, [1:4]) == [1, 2, 3, 4] | [1, 2, 3, 6]
is a logical vector of true and false values that you pass to if. In the examples below, do you know which of the if will consider the condition true?
if [true, true, true, true] %case 1
if [true, true, true, false] %case 2
if [false, true, true, true] %case 3
if [false, false, false, false] %case 4
It's only the first one. Thankfully for you, that's what you actually meant but it's better to be explicit and pass a scalar to if with:
if all(some_logical_vector)
Or even better, if you want to check that two vectors are identical use isequal which returns a vector, so
if isequal(a(c, 1:4), [1, 2, 3, 4])
The second and bigger problem is your made up syntax a == b | c. This is never going to mean if a is equal to b or a is equal to c (even if you use brackets). It means if (a is equal to b) or (c is true). And don't think you can use brackets to make it work, a == (b | c) means if a is equal to the result of (b or c is true). The proper way to write the expression is explicitly:
if a == b | a == c
So, for your test:
if isequal(a(c, 1:4), [1, 2, 3, 4]) || isequal(a(c, 1:4), [1,2 ,3 ,6])
However, the above can be expressed more simply with ismember, with the 'rows' option:
if ismember(a(c, :), [1, 2, 3, 4; 1, 2, 3, 6], 'rows')
  1 件のコメント
abhisrisai
abhisrisai 2019 年 8 月 2 日
Hi,
Thank you for the explanation. I now realize the mistakes I've made. This gives me better clarity. :)

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

その他の回答 (2 件)

Andrei Bobrov
Andrei Bobrov 2019 年 8 月 2 日
lo = a(:,3) == 4;
ii = cumsum([0;diff(lo) == 1]).*lo;
m = max(ii);
ii(ii == 0) = m + 1;
out = a(ii >= m,:);

Mariano
Mariano 2019 年 8 月 2 日
a = [1 2 3 4 % start point A
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 6 % start point B
1 2 4 5 % delete
1 2 4 5 % delete
1 2 3 5 % don't delete
1 2 3 7 % don't delete anything from below here.
1 2 4 5
1 2 4 5
1 2 4 5
1 2 4 5
1 2 3 5];
sp = find(ismember(a(:,4),[4,6])); % Find starting points
ep = find(ismember(a(:,4),[6,7])); % Find end points
n = length(ep); % How many? (assume number staring points = number
% end points)
dp = find(a(:,4)==5); % Candidates to be deleted
dr=[]; % DOES SOMEONE KNOW HOW TO VECTORIZE NEXT LOOP?
for j = 1:n
dr = [dr(:);dp(dp>sp(j)&dp<ep(j)-1)]; % Only delete rows between
% starting and end points
% Do not delete immediately
% before end point
end
a(dr,:)=[]

カテゴリ

Help Center および File ExchangeResizing and Reshaping Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by