Home > Blockchain >  Octave: A(~isnan(A)) results vector containing NaNs?
Octave: A(~isnan(A)) results vector containing NaNs?

Time:11-01

May be I don't get a basic thing, but I recently discovered this behaviour, and by now I don't understand what's happening:

A = [3 NaN .12 NaN NaN 9]
A =

            3          NaN         0.12          NaN          NaN            9

>> nansA = isnan(A)
nansA =

  0  1  0  1  1  0

>> nnansA = ~isnan(A)
nnansA =

  1  0  1  0  0  1

>> nnansA1 = ~isnan(A(1:end))
nnansA1 =

  1  0  1  0  0  1

>> nnansA2 = ~isnan(A(2:end))
nnansA2 =

  0  1  0  0  1

>> AnnansA1 = A(~isnan(A(1:end)))
AnnansA1 =

            3         0.12            9

>> **AnnansA2 = A(~isnan(A(2:end)))
AnnansA2 =

          NaN          NaN

What is happening here?

Does this happen in Matlab too?

I would expect something like ... AnnansA2 = 0.12 9

CodePudding user response:

What is happening here is that you're indexing A with a logical array of a different size and expect the indexing to not start at the beginning.

Let's deconstruct, from the inside:

>> A = [3 NaN .12 NaN NaN 9]
A =

   3.0000      NaN   0.1200      NaN      NaN   9.0000

>> # B a new array, with 5 elements (A had 6 elements)
>> B = A(2:end)
B =

      NaN   0.1200      NaN      NaN   9.0000

>> # mask is a logical array with 5 elements, like B, and not 6, like A.
>> # mask knows nothing about A or B.  It simply "selects" (indexes) the
>> # 1st, 3rd, and 4th element of any array.
>> mask = isnan (B)
mask =

  1  0  1  1  0

>> # Invert the mask, now "selects" the 2nd and 5th element of any array.
>> not_mask = ! mask
not_mask =

  0  1  0  0  1

>> # Return the 2nd and 5th element of A.
>> A(not_mask)
ans =

   NaN   NaN

I think you're surprised by the behaviour because you expect that A(2:end) "remembers" that it comes from A to index the right "region" of A. This does not happen, it's just a logical array that "remembers" nothing from which array it came (and often used to index different arrays).

As a side note, and answering one of your questions, Matlab behaviour is the same as Octave.

Anyway, what you're doing looks a bit odd, maybe do this instead:

A(! isnan (A))(2:end)

CodePudding user response:

You're off by one.

You need to do AnnansA2 = A(~isnan(A(1:end)))

If you want to return only the last two non-nans, index the result like;

ananIdxs = ~isnan(A)
AnnansA2 = A(ananIdxs(2:end))
  • Related