Home > Software design >  NumPy equivalent of MATLAB size()
NumPy equivalent of MATLAB size()

Time:03-17

Is there an equivalent to the MATLAB size() command in NumPy? I have found one other question (size of NumPy array) similar to this, but our questions are not the same. They had an array, so the size() and shape() functions should work fine.

In my case, I have a vector in some cases and an array in others. I want to use something like:

a = [ 20, 30, 40, 45, 50, 60] # angles
alpha = np.array(a) 
[mm,nn] = size(alpha)

I want it to return [mm, nn] = (6,1), but alpha.shape returns (6,). This poses a problem since the next part of the code is a for loop:

for i in range(nn):
    print (i) #do stuff
    for ii in range(mm):
        print (ii) #do stuff

In this case I have a vector so len(alpha) would work fine, but sometimes alpha is an array. I suppose I could use:

mm = alpha.size
nn = alpha.size/len(alpha)

But, I'd imagine there would be a better way. Is there a command like [mm,nn] = size(alpha) in MATLAB?

CodePudding user response:

.shape() returns a tuple. Since we can check the length of tuples, we can just define a custom size() function that inserts a 1 if the array is 1D:

def size(arr):
    if len(arr.shape) == 1:
        return arr.shape[0], 1
    return arr.shape

CodePudding user response:

shape IS the numpy equivalent.

In [127]: alpha = np.array([20, 30, 40, 45, 50, 60])
In [128]: alpha.shape
Out[128]: (6,)

MATLAB matrices are always 2d (or higher), so size will have 2 values. But numpy arrays can be 1d, or even 0d. So shape may just have 1 value as in (6,).

Sure you could construct mm,nn with these values:

In [129]: mm, nn = 6, 1

and even iterate on the ranges, but that doesn't help you access the elements of alpha:

In [130]: for i in range(nn):
     ...:     print(i, alpha[i])
     ...:     for ii in range(mm):
     ...:         print(ii)
     ...:         print(alpha[i, ii])
0 20
0
Traceback (most recent call last):
  Input In [130] in <module>
    print(alpha[i, ii])
IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed

alpha[0] is 20, but alpha[0,0] raises this error. alpha is 1d.

There are various ways of making a 2d array:

In [132]: beta = np.atleast_2d(alpha)
In [133]: beta
Out[133]: array([[20, 30, 40, 45, 50, 60]])
In [134]: beta.shape
Out[134]: (1, 6)
In [135]: beta[0, 3]
Out[135]: 45

or adding a trailing dimension:

In [136]: alpha[:, None].shape
Out[136]: (6, 1)

Sometimes we call these arrays "row vector" or "column vector", but in either case they are 2d arrays;

In [137]: beta
Out[137]: array([[20, 30, 40, 45, 50, 60]])
In [138]: alpha[:, None]
Out[138]: 
array([[20],
       [30],
       [40],
       [45],
       [50],
       [60]])

Sooner of later you need to become comfortable with the multiple-dimensions of numpy. Trying stick with the MATLAB notions will, in the long run, be frustrating. There are some older helps for way-ward MATLAB users, such as the np.matrix class, and https://numpy.org/doc/stable/user/numpy-for-matlab-users.html

In python it is possible to iterate on lists and arrays directly, and use enumerate if you also want an index:

In [140]: for i, v in enumerate(alpha):
     ...:     print(i, v, alpha[i])
0 20 20
1 30 30
2 40 40
3 45 45
4 50 50
5 60 60

But numpy we prefer not to iterate - not even with one level. And often we don't need to. (Same is/was true in MATLAB. Whole matrix opertions are preferable, though its jit compiling reduces the time penalty of iteration.)

In [141]: np.arange(alpha.shape[0])
Out[141]: array([0, 1, 2, 3, 4, 5])
In [142]: alpha
Out[142]: array([20, 30, 40, 45, 50, 60])
In [143]: alpha * np.arange(alpha.shape[0])
Out[143]: array([  0,  30,  80, 135, 200, 300])
  • Related