xirururu
xirururu

Reputation: 5508

how can I flatten an 2d numpy array, which has different length in the second axis?

I have a numpy array which looks like:

myArray = np.array([[1,2],[3]])

But I can not flatten it,

In: myArray.flatten()
Out: array([[1, 2], [3]], dtype=object)

If I change the array to the same length in the second axis, then I can flatten it.

In: myArray2 = np.array([[1,2],[3,4]])
In: myArray2.flatten()
Out: array([1, 2, 3, 4])

My Question is:

Can I use some thing like myArray.flatten() regardless the dimension of the array and the length of its elements, and get the output: array([1,2,3])?

Upvotes: 24

Views: 13709

Answers (3)

miradulo
miradulo

Reputation: 29690

myArray is a 1-dimensional array of objects. Your list objects will simply remain in the same order with flatten() or ravel(). You can use hstack to stack the arrays in sequence horizontally:

>>> np.hstack(myArray)
array([1, 2, 3])

Note that this is basically equivalent to using concatenate with an axis of 1 (this should make sense intuitively):

>>> np.concatenate(myArray, axis=1)
array([1, 2, 3])

If you don't have this issue however and can merge the items, it is always preferable to use flatten() or ravel() for performance:

In [1]: u = timeit.Timer('np.hstack(np.array([[1,2],[3,4]]))'\
   ....: , setup = 'import numpy as np')
In [2]: print u.timeit()
11.0124390125

In [3]: u = timeit.Timer('np.array([[1,2],[3,4]]).flatten()'\
   ....: , setup = 'import numpy as np')
In [4]: print u.timeit()
3.05757689476

Iluengo's answer also has you covered for further information as to why you cannot use flatten() or ravel() given your array type.

Upvotes: 21

Imanol Luengo
Imanol Luengo

Reputation: 15889

Well, I agree with the other answers when they say that hstack or concatenate do the job in this case. However, I would like to point that even if it 'fixes' the problem, the problem is not addressed properly.

The problem is that even if it looks like the second axis has different length, this is not true in practice. If you try:

>>> myArray.shape
(2,)
>>> myArray.dtype
dtype('O')    # stands for Object
>>> myArray[0]
[1, 2]

It shows you that your array is not a 2D array with variable size (as you might think), it is just a 1D array of objects. In your case, the elements are list, being the first element of your array a 2-element list and the second element of the array is a 1-element list.

So, flatten and ravel won't work because transforming 1D array to a 1D array results in exactly the same 1D array. If you have a object numpy array, it won't care about what you put inside, it will treat individual items as unkown items and can't decide how to merge them.

What you should have in consideration, is if this is the behaviour you want for your application. Numpy arrays are specially efficient with fixed-size numeric matrices. If you are playing with arrays of objects, I don't see why would you like to use Numpy instead of regular python lists.

Upvotes: 9

Zero
Zero

Reputation: 76917

np.hstack works in this case

In [69]: np.hstack(myArray)
Out[69]: array([1, 2, 3])

Upvotes: 3

Related Questions