1
votes

I have a problem with removing surplus rows in the end of the matrix. In general, I need to remove rows that contain a specific elements in a specific column, without using a loop. It seems easy but I still keep on getting some weird outcomes.

For simple example, let's have a 10x10 matrix A:

A=[1:10; 901:910; 201:210; 301:310; 701:710; 401:410; 601:610; 501:510; 801:810; 101:110];

And I want to remove (for better illustration just replace with ones) that rows from fourth to the last, whose third columns contain value higher than 600. Result should look like that:

|  1     2     3     4     5     6     7     8     9    10|
|901   902   903   904   905   906   907   908   909   910|
|201   202   203   204   205   206   207   208   209   210|
|301   302   303   304   305   306   307   308   309   310|
|  1     1     1     1     1     1     1     1     1     1|
|401   402   403   404   405   406   407   408   409   410|
|  1     1     1     1     1     1     1     1     1     1|
|501   502   503   504   505   506   507   508   509   510|
|  1     1     1     1     1     1     1     1     1     1|
|101   102   103   104   105   106   107   108   109   110|

My idea looks like that:

A(A(4:end,3)>600,:)=[1];

But the outcome is some nonsense matrix.

Thanks for your help!

2

2 Answers

1
votes
 A([false(3,1);A(4:end,3)>600],:)=1;

and as @yoda said, to remove the rows do:

 A([false(3,1);A(4:end,3)>600],:)=[];
0
votes

Firstly your problem is that entering a matrix inside a matrix means use the values of the matrix as indices. since your matrix only has zeros and ones (as a result of the "<" operator) you got a weird result.

To answer your question, you need to replace the matrix with a smaller matrix. something like: A = new_matrix

new_matrix is generated out of A by taking only the rows you want.

new_matrix = A(row_indices, :)

Where row_indices is the vector of indices you want to keep. To build that you can start with a zeros-ones vector and apply find (which will yield the indices with ones). So we want:

row_indices = find([1,1,1, A(4:end,3).'<600])

The first 3 ones are because you always want the first 3 lines. So putting everything together gives

A = A(find([1,1,1,A(4:end,3).'<600]),:)

Running this on your example values :

>> A=[1:10; 901:910; 201:210; 301:310; 701:710; 401:410; 601:610; 501:510; 801:810; 101:110];
>> A(find([1,1,1,A(4:end,3).'<600]),:)

ans =

     1     2     3     4     5     6     7     8     9    10
   901   902   903   904   905   906   907   908   909   910
   201   202   203   204   205   206   207   208   209   210
   301   302   303   304   305   306   307   308   309   310
   401   402   403   404   405   406   407   408   409   410
   501   502   503   504   505   506   507   508   509   510
   101   102   103   104   105   106   107   108   109   110

BTW, changing these rows to ones is just as easy:

A(find([0,0,0,A(4:end,3).'>600]),:) = 1