AlejandroVK
AlejandroVK

Reputation: 7605

How to iterate a 3D numpy array

Forgive me if something about what I'm about to ask sounds stupid, I've just started with numpy and multi-dimensional arrays in Python :D

That said, I've got a 3D array of [85 x 235 x 327]. Each position holds a discrete value, and, in most cases, NaN.

First thing I'd like to do is iterate over this array and remove the NaN values, building a new array that contains only valid values.

I've tried this:

    for index,value in np.ndenumerate( data ):
    print "index value: " + str(index)
    print "value: " + str(value)

But this will only execute one pass...not really sure what ndenumerate does.

Also tried this:

indexOne = waves.shape[0]
indexTwo = waves.shape[1]
indexThree = waves.shape[2]

for i in range(indexOne):
    for j in range(indexTwo):
        for k in range(indexThree):
            a = waves[i,j,k]
            print a.data

And while this does iterates...taking into account that I have 6531825 points...this is going to take forever...thus, is there any built-in function to remove values from an existing array without having to iterate all the elements?

Upvotes: 2

Views: 3104

Answers (2)

senderle
senderle

Reputation: 150957

It depends a little on what you want the final array to look like. Here's something that literally does what you say. However, it doesn't preserve the shape. Setting up the array:

>>> a = numpy.linspace(0, 26, 27).reshape(3, 3, 3)
>>> a[1][0] = numpy.nan
>>> a
array([[[  0.,   1.,   2.],
        [  3.,   4.,   5.],
        [  6.,   7.,   8.]],

       [[ nan,  nan,  nan],
        [ 12.,  13.,  14.],
        [ 15.,  16.,  17.]],

       [[ 18.,  19.,  20.],
        [ 21.,  22.,  23.],
        [ 24.,  25.,  26.]]])

Then you can create a mask with isnan:

>>> numpy.isnan(a)
array([[[False, False, False],
        [False, False, False],
        [False, False, False]],

       [[ True,  True,  True],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False]]], dtype=bool)

And use it to index a:

>>> a[~numpy.isnan(a)]
array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,  12.,  13.,
        14.,  15.,  16.,  17.,  18.,  19.,  20.,  21.,  22.,  23.,  24.,
        25.,  26.])

You could use a similar trick to do many other things with nan values. For example:

>>> a[numpy.isnan(a)] = 0
>>> a
array([[[  0.,   1.,   2.],
        [  3.,   4.,   5.],
        [  6.,   7.,   8.]],

       [[  0.,   0.,   0.],
        [ 12.,  13.,  14.],
        [ 15.,  16.,  17.]],

       [[ 18.,  19.,  20.],
        [ 21.,  22.,  23.],
        [ 24.,  25.,  26.]]])

Upvotes: 1

Stefano Sanfilippo
Stefano Sanfilippo

Reputation: 33046

nan_to_num does exactly what you want:

Replace nan with zero and inf with finite numbers.

Returns an array or scalar replacing Not a Number (NaN) with zero, (positive) infinity with a very large number and negative infinity with a very small (or negative) number.

Use it like:

x = np.nan_to_num(x)

Upvotes: 1

Related Questions