Shejo284
Shejo284

Reputation: 4771

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?

Upvotes: 5

Views: 3072

Answers (2)

Saullo G. P. Castro
Saullo G. P. Castro

Reputation: 58955

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) ]

Upvotes: 5

James Porter
James Porter

Reputation: 1933

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.

Upvotes: 1

Related Questions