A ndarray stored as a 1d buffer - just a block of memory. The multidimensional nature of the array is created by the shape and strides and the code that uses them.
The numpy developers decided to allow an arbitrary number of dimensions, so the form and steps are represented as tuples of any length, including 0 and 1.
In contrast, MATLAB was built around FORTRAN programs that were designed for matrix operations. In the early days, everything in MATLAB was a 2d matrix. Around the year 2000 (v3.5), it was generalized to allow more than 2d, but no less. numpy np.matrix still follows that old limitation is 2d MATLAB.
If you come from the world of MATLAB, you are used to these 2 dimensions and the difference between a row vector and a column vector. But in mathematics and physics, which are not affected by MATLAB, the vector is the 1st array. Python lists are inherently 1d, as are c arrays. To get 2d, you must have lists of lists or arrays of pointers to arrays, with x[1][2] indexing style.
Look at the shape and steps of this array and its options:
In [48]: x=np.arange(10) In [49]: x.shape Out[49]: (10,) In [50]: x.strides Out[50]: (4,) In [51]: x1=x.reshape(10,1) In [52]: x1.shape Out[52]: (10, 1) In [53]: x1.strides Out[53]: (4, 4) In [54]: x2=np.concatenate((x1,x1),axis=1) In [55]: x2.shape Out[55]: (10, 2) In [56]: x2.strides Out[56]: (8, 4)
MATLAB adds new dimensions at the end. It arranges its values as an array order='F' and can easily change the matrix (n, 1) to a (n, 1,1,1). numpy defaults to order='C' and it easily extends the dimension of the array at the beginning. Understanding this is important when using translation.
Thus, x1 + x is (10.1) + (10,) => (10.1) + (1.10) => (10.10)
Due to broadcasting, the array (n,) more like (1,n) than (n,1) . A 1d array looks more like a row matrix than a single column.
In [64]: np.matrix(x) Out[64]: matrix([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) In [65]: _.shape Out[65]: (1, 10)
The point with concatenate is that it requires appropriate sizes. It does not use broadcast to adjust the size. There are several stack functions that facilitate this limitation, but they do this by adjusting the sizes before using concatenate . Look at their code (readable by Python).
Therefore, an experienced numpy user should be comfortable with this generic shape tuple, including empty () (array 0d), (n,) 1d and above. For more advanced actions, it also helps to cope with the steps (look, for example, at the steps and the form of transposition).