简体   繁体   中英

Python numpy: Dimension [0] in vectors (n-dim) vs. arrays (nxn-dim)

I'm currently wondering how the numpy array behaves. I feel like the dimensions are not consistent from vectors ( Nx1 dimensional) to 'real arrays' ( NxN dimensional).

I dont get, why this isn't working:

a = array(([1,2],[3,4],[5,6]))
concatenate((a[:,0],a[:,1:]), axis = 1)
# ValueError: all the input arrays must have same number of dimensions

It seems like the : (at 1:] ) makes the difference, but ( :0 is not working)

Thanks in advance!

Detailled Version: So I would expect that shape(b)[0] references the vertical direction in ( Nx1 arrays), like in an 2D ( NxN ) array. But it seems like dimension [0] is the horizontal direction in arrays ( Nx1 arrays)?

from numpy import *

a = array(([1,2],[3,4],[5,6]))
b = a[:,0]
print shape(a)  # (3L, 2L), [0] is vertical
print a         # [1,2],[3,4],[5,6]
print shape(b)  # (3L, ), [0] is horizontal
print b         # [1 3 5]

c = b * ones((shape(b)[0],1)) 
print shape(c)  # (3L, 3L), I'd expect (3L, 1L)
print c         # [[ 1.  3.  5.], [ 1.  3.  5.], [ 1.  3.  5.]]

What did I get wrong? Is there a nicer way than

d = b * ones((1, shape(b)[0]))
d = transpose(d)
print shape(d)  # (3L, 1L)
print d         # [[ 1.], [ 3.], [ 5.]]

to get the ( Nx1 ) vector that I expect or want?

There are two overall issues here. First, b is not an (N, 1) shaped array, it is an (N,) shaped array. In numpy, 1D and 2D arrays are different things. 1D arrays simply have no direction. Vertical vs. horizontal, rows vs. columns, these are 2D concepts.

The second has to do with something called " broadcasting ". In numpy arrays, you are able to broadcast lower-dimensional arrays to higher-dimensional ones, and the lower-dimensional part is applied elementwise to the higher-dimensional one.

The broadcasting rules are pretty simple:

When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions, and works its way forward. Two dimensions are compatible when

they are equal, or

one of them is 1

In your case, it starts with the last dimension of ones((shape(b)[0],1)) , which is 1 . This meets the second criteria. So it multiplies the array b elementwise for each element of ones((shape(b)[0],1)) , resulting in a 3D array.

So it is roughly equivalent to:

c = np.array([x*b for x in ones(shape(b))])

Edit:

To answer your original question, what you want to do is to keep both the first and second arrays as 2D arrays.

numpy has a very simple rule for this: indexing reduces the number of dimensions, slicing doesn't. So all you need is to have a length-1 slice. So in your example, just change a[:,0] to a[:,:1] . This means 'get every column up to the second one'. Of course that only includes the first column, but it is still considered a slice operation rather than getting an element, so it still preservers the number of dimensions:

>>> print(a[:, 0])
[1 3 5]
>>> print(a[:, 0].shape)
(3,)
>>> print(a[:, :1])
[[1]
 [3]
 [5]]
>>> print(a[:, :1].shape)
(3, 1)
>>> print(concatenate((a[:,:1],a[:,1:]), axis = 1))
[[1 2]
 [3 4]
 [5 6]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM