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])