J Doe.
J Doe.

Reputation: 5

Multidimensional array in numpy

I have an array of shape (5,2) which each row consist of an array of shape (4,3,2) and a float number.

After I slice that array[:,0], I get an array of shape (5,) which each element has shape of (4,3,2), instead of an array of shape (5,4,3,2) (even if I'd use np.array()).

Why?

Edited

Example:

a1 = np.arange(50).reshape(5, 5, 2)
a2 = np.arange(50).reshape(5, 5, 2)

b1 = 15.0
b2 = 25.0

h = []
h.append(np.array([a1, b1]))
h.append(np.array([a2, b2]))

h = np.array(h)[:,0]
np.shape(h) # (2,)
np.shape(h[0]) # (5, 5, 2)
np.shape(h[1]) # (5, 5, 2)
h = np.array(h)
np.shape(h) # (2,) Why not (2, 5, 5, 2)?

Upvotes: 0

Views: 1577

Answers (3)

hpaulj
hpaulj

Reputation: 231738

In [121]: a1.dtype, a1.shape
Out[121]: (dtype('int32'), (5, 5, 2))
In [122]: c1 = np.array([a1,b1])
In [123]: c1.dtype, c1.shape
Out[123]: (dtype('O'), (2,))

Because a1 and b1 are different shaped objects (b1 isn't even an array), an array made from them will have dtype object. And the h made from several continues to be object dtype.

In [124]: h = np.array(h)
In [125]: h.dtype, h.shape
Out[125]: (dtype('O'), (2, 2))
In [126]: h[:,1]
Out[126]: array([15.0, 25.0], dtype=object)
In [127]: h[:,0].dtype
Out[127]: dtype('O')

After the appends, h (as an array) is object dtype. The 2nd column is the b1 and b2 values, the 1st column the a1 and a2.

Some form of concatenate is required to combine those a1 a2 arrays into one. stack does it on a new axis.

In [128]: h[0,0].shape
Out[128]: (5, 5, 2)
In [129]: np.array(h[:,0]).shape     # np.array doesn't cross the object boundary
Out[129]: (2,)
In [130]: np.stack(h[:,0]).shape
Out[130]: (2, 5, 5, 2)
In [131]: np.concatenate(h[:,0],0).shape
Out[131]: (10, 5, 2)

Turning the (2,) array into a list, does allow np.array to recombine the elements into a higher dimensional array, just as np.stack does:

In [133]: np.array(list(h[:,0])).shape
Out[133]: (2, 5, 5, 2)

Upvotes: 1

akuiper
akuiper

Reputation: 215127

You have an array of objects; You can use np.stack to convert it to the shape you need if you are sure all the sub elements have the same shape:

np.stack(a[:,0])

a = np.array([[np.arange(24).reshape(4,3,2), 1.]]*5)

a.shape
# (5, 2)

a[:,0].shape
# (5,)

a[:,0][0].shape
# (4, 3, 2)

np.stack(a[:,0]).shape
# (5, 4, 3, 2)

Upvotes: 2

holdenweb
holdenweb

Reputation: 37193

You appear to believe that Numpy can magically divine your intent. As @Barmar explains in the comments, when you slice a shape(5,2) array with [:, 0] you get all rows of the first column of that array. Each element of that slice is a shape(4,3,2) array. Numpy is giving you exactly what you asked for.

If you want to convert that into a shape(5,4,3,2) array you'll need to perform further processing to extract the elements from the shape(4,3,2) arrays.

Upvotes: 0

Related Questions