127

Say now I have a numpy array which is defined as,

[[1,2,3,4],
[2,3,NaN,5],
[NaN,5,2,3]]

Now I want to have a list that contains all the indices of the missing values, which is [(1,2),(2,0)] at this case.

Is there any way I can do that?

xxx222
  • 2,980
  • 5
  • 34
  • 53

3 Answers3

216

np.isnan combined with np.argwhere

x = np.array([[1,2,3,4],
              [2,3,np.nan,5],
              [np.nan,5,2,3]])
np.argwhere(np.isnan(x))

output:

array([[1, 2],
       [2, 0]])
michael_j_ward
  • 4,369
  • 1
  • 24
  • 25
  • 1
    How to do the same for an array with float values ? – Deepraj Chanda Jun 08 '21 at 16:51
  • 1
    `argwhere` rocks! I have an ancillary question though. Given it returns a list of indices, is there any way in numpy to coalesce those indices into a minimal list of slices. Fro example I get back `[[1,1],[1,2],[1,3],[3,8],[4,8],[5,8]]` and would like `[[1,1:4],[3:6,8]]` primarily because my data does come in nice windows and the list of indices is huge. – Bernd Wechner Aug 04 '22 at 06:58
23

You can use np.where to match the boolean conditions corresponding to Nan values of the array and map each outcome to generate a list of tuples.

>>>list(map(tuple, np.where(np.isnan(x))))
[(1, 2), (2, 0)]
Nickil Maveli
  • 29,155
  • 8
  • 82
  • 85
16

Since x!=x returns the same boolean array with np.isnan(x) (because np.nan!=np.nan would return True), you could also write:

np.argwhere(x!=x)

However, I still recommend writing np.argwhere(np.isnan(x)) since it is more readable. I just try to provide another way to write the code in this answer.

johnnyasd12
  • 636
  • 7
  • 11