user1584253
user1584253

Reputation: 1005

Convert elements of multi-dimensional numpy array to float32

I have a complicated nested numpy array which contains list. I am trying to converted the elements to float32. However, it gives me following error:

ValueError                                Traceback (most recent call last)
<ipython-input-225-22d2824961c2> in <module>
----> 1 x_train_single.astype(np.float32)

ValueError: setting an array element with a sequence.

Here is the code and sample input:

    x_train_single.astype(np.float32)

    array([[ list([[[0, 0, 0, 0, 0, 0]], [-1.0], [0]]),
    list([[[0, 0, 0, 0, 0, 0], [173, 8, 172, 0, 0, 0]], [-1.0], [0]])
   ]])

Upvotes: 1

Views: 882

Answers (3)

Paul Panzer
Paul Panzer

Reputation: 53089

As your array contains lists of different sizes and nesting depths, I doubt that there is a simple or fast solution.

Here is a "get-the-job-done-no-matter-what" approach. It comes in two flavors. One creates arrays for leaves, the other one lists.

>>> a
array([[list([[[0, 0, 0, 0, 0, 0]], [-1.0], [0]]),
        list([[[0, 0, 0, 0, 0, 0], [173, 8, 172, 0, 0, 0]], [-1.0], [0]])]],
      dtype=object)

>>> def mkarr(a):
...     try:
...         return np.array(a,np.float32)
...     except:
...         return [*map(mkarr,a)]
... 
>>> def mklst(a):
...     try:
...         return [*map(mklst,a)]
...     except:
...         return np.float32(a)
... 

>>> np.frompyfunc(mkarr,1,1)(a)
array([[list([array([[0., 0., 0., 0., 0., 0.]], dtype=float32), array([-1.], dtype=float32), array([0.], dtype=float32)]),
        list([array([[  0.,   0.,   0.,   0.,   0.,   0.],
       [173.,   8., 172.,   0.,   0.,   0.]], dtype=float32), array([-1.], dtype=float32), array([0.], dtype=float32)])]],
      dtype=object)

>>> np.frompyfunc(mklst,1,1)(a)
array([[list([[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [-1.0], [0.0]]),
        list([[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [173.0, 8.0, 172.0, 0.0, 0.0, 0.0]], [-1.0], [0.0]])]],
      dtype=object)

Upvotes: 1

hpaulj
hpaulj

Reputation: 231540

Try this:

np.array(x_train_single.tolist())   

Looks like you have a (1,1) shaped array, where the single element is a list. And the sublists a consistent in size.

I expect you will get an array with shape (1, 1, 1, 11, 6) and int dtype.

or:

np.array(x_train_single[0,0])

Again this extracts the list from the array, and then makes an array from that.

My answer so far was based on the display:

array([[list([[[173, 8, 172, 0, 0, 0], [512, 58, 57, 0, 0, 0],  
     ...: [513, 514, 0, 0, 0, 0], [515, 189, 516, 0, 0, 0], [309, 266, 0, 0, 0, 
     ...: 0],  
     ...: [32, 310, 0, 0, 0, 0], [271, 58, 517, 0, 0, 0], [164, 40, 0, 0, 0, 0],
     ...:  [38, 32, 60, 0, 0, 0], [38, 83, 60, 0, 0, 0], [149, 311, 0, 0, 0, 0]]
     ...: ])]])

The new display is more complicated

array([[ list([[[0, 0, 0, 0, 0, 0]], [-1.0], [0]]), 
     ...:     list([[[0, 0, 0, 0, 0, 0], [173, 8, 172, 0, 0, 0]], [-1.0], [0]])]])                                                                

because the inner lists differ in size. It can't be made into a numeric dtype array.

It can be turned into a (1,2,3) shape array, but still object dtype with 1d list elements.

Upvotes: 0

mujjiga
mujjiga

Reputation: 16906

if number of columns is fixed then

np.array([l.astype(np.float) for l in x_train_single.squeeze()])

But it will remove the redundant dimensions, convert everything into numpy array.

Before: (1, 1, 1, 11, 6)

After: (11,6)

Upvotes: 0

Related Questions