Eka
Eka

Reputation: 15000

Is there a numpy way to reduce arrays?

I have this numpy array which is a concatention of other numpy arrays

array([array([[ 0.,  1.,  0.,  0.,  1.,  0.]]),
       array([[ 1.,  0.,  0.,  1.,  0.,  0.]]),
       array([[ 0.,  0.,  0.,  0.,  1.,  1.]]),
       array([[ 0.,  1.,  0.,  0.,  0.,  1.]]),
       array([[ 0.,  1.,  0.,  1.,  0.,  0.]]),
       array([[ 1.,  0.,  0.,  0.,  0.,  1.]])], dtype=object)

its current shape is (6,). what I want is this with a shape (6,6)

array([[ 0.,  1.,  0.,  0.,  1.,  0.],
       [ 1.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  1.],
       [ 0.,  1.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  1.]], dtype=object)

Is there a numpy way to solve this problem or do I have to loop through the arrays and append it?

Upvotes: 0

Views: 570

Answers (2)

hpaulj
hpaulj

Reputation: 231385

If the display is accurate, and the array really is (6,), then we have to recreate it with:

In [27]: array=np.array
In [28]: alist = [array([[ 0.,  1.,  0.,  0.,  1.,  0.]]),
    ...:        array([[ 1.,  0.,  0.,  1.,  0.,  0.]]),
    ...:        array([[ 0.,  0.,  0.,  0.,  1.,  1.]]),
    ...:        array([[ 0.,  1.,  0.,  0.,  0.,  1.]]),
    ...:        array([[ 0.,  1.,  0.,  1.,  0.,  0.]]),
    ...:        array([[ 1.,  0.,  0.,  0.,  0.,  1.]])]
    ...:        
In [29]: A = np.empty((6,),object)
In [30]: A
Out[30]: array([None, None, None, None, None, None], dtype=object)
In [31]: A[:]=alist
In [32]: A
Out[32]: 
array([array([[ 0.,  1.,  0.,  0.,  1.,  0.]]),
       array([[ 1.,  0.,  0.,  1.,  0.,  0.]]),
       array([[ 0.,  0.,  0.,  0.,  1.,  1.]]),
       array([[ 0.,  1.,  0.,  0.,  0.,  1.]]),
       array([[ 0.,  1.,  0.,  1.,  0.,  0.]]),
       array([[ 1.,  0.,  0.,  0.,  0.,  1.]])], dtype=object)

reshape does not work:

In [33]: A.reshape(6,6)
...
ValueError: cannot reshape array of size 6 into shape (6,6)

But the array can be treated as a list, and given to concatenate:

In [34]: np.concatenate(A, axis=1)
Out[34]: 
array([[ 0.,  1.,  0.,  0.,  1.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,
         0.,  0.,  0.,  1.,  1.,  0.,  1.,  0.,  0.,  0.,  1.,  0.,  1.,
         0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.]])
In [35]: np.concatenate(A, axis=0)
Out[35]: 
array([[ 0.,  1.,  0.,  0.,  1.,  0.],
       [ 1.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  1.],
       [ 0.,  1.,  0.,  0.,  0.,  1.],
       [ 0.,  1.,  0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  1.]])

Concatenate on the list works just as well: np.concatenate(alist, axis=0)

I should note that the resulting array is dtype float, not object. It could be converted with astype, but who would want that?


Simple copy-n-paste produces a 3d array, since the outer array ignores the inner division and creates as high-a-dimensional array as it can:

In [37]: array([array([[ 0.,  1.,  0.,  0.,  1.,  0.]]),
    ...:        array([[ 1.,  0.,  0.,  1.,  0.,  0.]]),
    ...:        array([[ 0.,  0.,  0.,  0.,  1.,  1.]]),
    ...:        array([[ 0.,  1.,  0.,  0.,  0.,  1.]]),
    ...:        array([[ 0.,  1.,  0.,  1.,  0.,  0.]]),
    ...:        array([[ 1.,  0.,  0.,  0.,  0.,  1.]])])       
Out[37]: 
array([[[ 0.,  1.,  0.,  0.,  1.,  0.]],

       [[ 1.,  0.,  0.,  1.,  0.,  0.]],
        ...
       [[ 1.,  0.,  0.,  0.,  0.,  1.]]])
In [38]: _.shape
Out[38]: (6, 1, 6)

So we need to careful how we recreate cases like this.

Upvotes: 1

JBernardo
JBernardo

Reputation: 33397

You should try this:

my_array = my_array.reshape(6,6)

It works with the above array when pasted as is as it will remove the third dimension. Other methods like vstack and concatenate as shown on @Divikar comment above should work as well for this purpose

Upvotes: 1

Related Questions