Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy array get the subset/slice of an array which is not NaN

I have an array of size: (50, 50). Within this array there is a slice of size (20,10). Only this slice contains data, the remainder is all set to nan.

How do I cut this slice out of my large array?

like image 504
Shejo284 Avatar asked Jun 15 '13 18:06

Shejo284


2 Answers

You can get this using fancy indexing to collect the items that are not NaN:

a = a[ np.logical_not( np.isnan(a) ) ].reshape(20,10)

or, alternatively, as suggested by Joe Kington:

a = a[ ~np.isnan(a) ]
like image 115
Saullo G. P. Castro Avatar answered Nov 14 '22 22:11

Saullo G. P. Castro


Do you know where the NaNs are? If so, something like this should work:

newarray = np.copy(oldarray[xstart:xend,ystart:yend])

where xstart and xend are the beginning and end of the slice you want in the x dimension and similarly for y. You can then delete the old array to free up memory if you don't need it anymore.

If you don't know where the NaNs are, this should do the trick:

# in this example, the starting array is A, numpy is imported as np
boolA = np.isnan(A) #get a boolean array of where the nans are
nonnanidxs = zip(*np.where(boolA == False)) #all the indices which are non NaN
#slice out the nans
corner1 = nonnanidxs[0]
corner2 = nonnanidxs[-1]
xdist = corner2[0] - corner1[0] + 1
ydist = corner2[1] - corner1[1] + 1
B = copy(A[corner1[0]:corner1[0]+xdist,corner1[1]:corner1[1]+ydist])
#B is now the array you want

Note that this would be pretty slow for large arrays because np.where looks through the whole thing. There's an open issue in the number bug tracker for a method that finds the first index equal to some value and then stops. There might be a more elegant way to do this, this is just the first thing that came to my head.

EDIT: ignore, sgpc's answer is much better.

like image 43
James Porter Avatar answered Nov 14 '22 23:11

James Porter