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

1 vue (au cours des 30 derniers jours)
abhisrisai
abhisrisai le 2 Août 2019
Commenté : abhisrisai le 2 Août 2019
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

Réponse acceptée

Guillaume
Guillaume le 2 Août 2019
Modifié(e) : Guillaume le 2 Août 2019
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 commentaire
abhisrisai
abhisrisai le 2 Août 2019
Hi,
Thank you for the explanation. I now realize the mistakes I've made. This gives me better clarity. :)

Connectez-vous pour commenter.

Plus de réponses (2)

Andrei Bobrov
Andrei Bobrov le 2 Août 2019
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 le 2 Août 2019
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,:)=[]

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by