Replacing the column of array elements with NaN.

4 visualizaciones (últimos 30 días)
pr
pr el 29 de Mayo de 2014
Respondida: Andrei Bobrov el 29 de Mayo de 2014
Given an array A = [0 11; 0.1 2; 0.2 5; 0.3 3; 0.4 6; 0.5 7; 0.6 10; 0.7 4; 0.8 5; 0.9 6; 1 12]; and array x = [0.2,0.4 ; 0.6,0.9];. I would like to manipulate the second column. with respect to the array x. Out_Arr = [0 NaN; 0.1 NaN; 0.2 5; 0.3 3; 0.4 6; 0.5 NaN; 0.6 10; 0.7 4; 0.8 5; 0.9 6; 1 NaN]; Could any one help on this?

Respuesta aceptada

Geoff Hayes
Geoff Hayes el 29 de Mayo de 2014
Editada: Geoff Hayes el 29 de Mayo de 2014
It seems that the rows of x indicate which ranges of values in A should be preserved, with the rest of the entries in the second column of matrix A set to NaN. A looping solution is as follows:
% pre-allocate array of indices indicating values in A to keep/preserve
keepInA = zeros(size(A(:,2)));
% loop over all rows of x
for i=1:size(x,1)
% find where in the first column of A are the two values for the ith row of x
mems = ismember(A(:,1),x(i,:));
% set that range in keepInA to be all ones indicating all values in that range
% are to be kept (there's is probably a better way to do this)
keepInA(find(mems,1,'first'):find(mems,1,'last')) = 1;
% now just set all those elements in the second row of A to be NaN if they
% are NOT to be kept (i.e. zero)
A(keepInA==0,2) = NaN;
The above assumes that there is no overlap of ranges in x and that those ranges can be found in A. If the assumptions are not true, then the above code would have to be modified.
  2 comentarios
pr
pr el 29 de Mayo de 2014
Editada: pr el 29 de Mayo de 2014
Can this be achieved without using for loop?? For eg: Finding the index and replacing ??
Geoff Hayes
Geoff Hayes el 29 de Mayo de 2014
I think that there will always be a loop, whether it is implicit or explicit like the above. Here is a crazy different approach that has no explicit loop:
y = x'; % transpose x so that ranges are column-wise
z = ismember(A(:,1),y(:)); % note that the second input is a column
k = or(z,mod(cumsum(z),2));
A(k==0,2) = NaN;
So what is going on in the above? We convert x to a column vector (via the assignment to y and y(:)) so that the ismember returns a combination of the outputs from ismember in the previous code but as one vector:
z =
0
0
1
0
1
0
1
0
0
1
0
Which is almost okay but we need to fill in all the zeroes in between two neighbouring ones so that we get the correct ranges. If we do a cumulative sum via cumsum then we see
0
0
1
1
2
2
3
3
3
4
4
which is not quite what we want. In fact, all we really want are the odd numbers and the first even number that follows the set of consecutive odd numbers. We can remove all even numbers via mod(cumsum(z),2)) and then "add" back in the missing ones (corresponding to 0.4 and 0.9) via or, so that
or(z,mod(cumsum(z),2));
0
0
1
1
1
0
1
1
1
1
0
is the list of indices that we wish to preserve/keep. So the 5 lines (or so) of the above for loop could be replaced by the 3-4 lines from above. Is it any better? Probably not as this logic is more confusing to follow than the straight-forward for loop.

Iniciar sesión para comentar.

Más respuestas (3)

Andrei Bobrov
Andrei Bobrov el 29 de Mayo de 2014
Out_Arr = A;
Out_Arr(all(bsxfun(@lt,A(:,1),x(:,1)')|bsxfun(@gt,A(:,1),x(:,2)'),2),2) = nan;

John
John el 29 de Mayo de 2014
Explain the relationship of your x and Out_Arr.
  1 comentario
pr
pr el 29 de Mayo de 2014
Take the first row of x i.e [0.2,0.4]. If you take the first column of A values >= 0.2 and <= 0.4 the corresponding rows of the 2nd column doesn't change. and similarly for second row i.e values >=0.6 and <=0.9 the corresponding rows of the second column doesn't change and making all other elements of the 2nd column A to NaN.

Iniciar sesión para comentar.


Udit Gupta
Udit Gupta el 29 de Mayo de 2014
This should do the trick -
index1 = A(:,1)<x(1,1) | A(:,1)>x(1,2);
index2 = A(:,1)<x(2,1) | A(:,1)>x(2,2);
A(index1 & index2, 2) = NaN
  2 comentarios
pr
pr el 29 de Mayo de 2014
How can I make it generalize if the number of rows of array x varies???
Udit Gupta
Udit Gupta el 29 de Mayo de 2014
Put it in a loop and give replace x(1,1), x(1,2) etc. by x(i,1) and x(1,2). You can successively apply and (&) operator to the index and at the end of the loop perform the operation.

Iniciar sesión para comentar.

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Etiquetas

Aún no se han introducido etiquetas.

Community Treasure Hunt

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

Start Hunting!

Translated by