2
votes

Say I have a 1-D vector named s composed of 0,3,6,9.

In MATLAB the shape is denoted (1,4). i.e. a 1x4 row vector.

But in numpy the shape is given as (4,). Why? Shouldn't this notation denote a 4x1 vector, since python also uses the row x col convention?

Now if I want to reshape the row vector, in MATLAB I would type reshape(s,[4,1]) to get a column vector.

I would assume the standard notation for an equivalent operation is s.reshape(4,1). But in the documentation I see s.reshape(-1,1). Why? Is one syntax better than the other? What does -1 mean in this context?

1
numpy has real 1d arrays, - hpaulj
rows and columns are convenient descriptors for 2d arrays. They are not formally defined or used. numpy always talks about axes. - hpaulj
That -1 in reshape is 'what ever works'. MATLAB uses [] for that. - hpaulj

1 Answers

2
votes

Step back from numpy a moment and look at Python lists:

In [165]: alist = [0,3,6,9]                                                     
In [166]: alist                                                                 
Out[166]: [0, 3, 6, 9]
In [167]: alist[1]                                                              
Out[167]: 3

This 3 is a scalar; I'd get an error if I tried index it, alist[1][0].

Now make a list of lists:

In [168]: alist = [[0],[3],[6],[9]]                                             
In [169]: alist                                                                 
Out[169]: [[0], [3], [6], [9]]
In [170]: alist[1]                                                              
Out[170]: [3]
In [171]: alist[1][0]                                                           
Out[171]: 3

I can index it twice.

In Octave, the poor man's MATLAB

>> x = [0,3,6,9];
>> x(2)
ans =  3
>> size(x)
ans =
   1   4

>> size(x(2))
ans =
   1   1

x(2) is still a 2d matrix; I could index it indefinitely, x(2)(1)(1)(1). Size itself is a 2d matrix; everything in MATLAB is 2d (or higher).

>> size(size(x))
ans =
   1   2

Back in Python/numpy:

In [172]: arr = np.array([0,3,6,9])                                             
In [173]: arr.shape                                                             
Out[173]: (4,)             # a 1 element tuple

In [175]: arr[1]                                                                
Out[175]: 3
In [176]: type(Out[175])                                                        
Out[176]: numpy.int64
In [177]: Out[175].shape                                                        
Out[177]: ()

The result of indexing an element of that 1d array is a numpy scalar object, with a 0d shape. https://docs.scipy.org/doc/numpy/reference/arrays.scalars.html

Judging from many questions, it seems that MATLAB users have trouble conceiving of an array with 1 or even 0 dimensions. That lower 2d bound becomes thoroughly ingrained in their thinking. It also seems to be foundational to some (if not all) versions of linear algebra. There are matrices, and row vectors and column vectors, but not 'plain' vectors.

But numpy runs in Python, and the behavior of its arrays is consistent with Python lists. And logically consistent with itself.

Here's what a 'column' vector and 'row' vector look like. Note the shapes - both 2 element tuples. And nesting of brackets (2 levels). The similarity to nested list is intentional.

In [178]: arr = np.array([[0],[3],[6],[9]])                                     
In [179]: arr.shape                                                             
Out[179]: (4, 1)
In [180]: arr                                                                   
Out[180]: 
array([[0],
       [3],
       [6],
       [9]])
In [181]: arr = np.array([[0,3,6,9]])                                           
In [182]: arr.shape                                                             
Out[182]: (1, 4)
In [183]: arr                                                                   
Out[183]: array([[0, 3, 6, 9]])