In Matlab there is no concept of 1 dimensional array. All arrays have at least two dimensions. All "vectors" are either "row vectors" (1xn arrays) or "column vectors" (nx1 arrays).
In NumPy, on the other hand, arrays can also be one dimensional. So there is the concept of "pure vector" (dimension n), "row vector" (dimension 1xn) and "column vectors" (dimension nx1).
This is giving me headaches now that I am moving from Matlab to Python.
As an example consider the case where I have to shift the rows of an n x k (n is generally big, but k can be 1) matrix, call it A, down by one row and then add a row of zeros a the first row.
In Matlab I would just do
[n, k] = size(A);
B = [zeros(1,k); A(1:end-1,:)];
In Numpy, I would like this to work not only on a 2-dimensional input but also on a 1-dimentional one. So a working solution would be
import numpy as np
if A.ndim == 1:
B = np.concatenate((np.zeros(1), A[:-1]), axis=0)
if A.ndim == 2:
(n, k) = A.shape
B = np.concatenate((np.zeros((1,k)), A[:-1,:]), axis=0)
But this is way to heavy. Is there a better (more coincise) way?
More in general, I always have this problem: if I wrote a function that takes a 2 dimensional array (n x k), call it arr
, where k can very well be 1, the function might fail on 1 dimensional arrays (for example if I do arr[0,:]
).
But I would like it to work also on 1 dimensional arrays, since they are morally the same thing as 2 dimensional arrays in which one of the dimensions is 1.
Sure one way out would be to put something like
if arr.ndim == 1
arr = arr.reshape((arr.shape[0],1))
at the very beginning of the function, so that then the function is guaranteed to have a 2 dimensional array to work with.
But this is not fully satisfactory. For example, it could be the case that my function returns an array of the same shape of the input (nxk). But if the input were one dimensional, I would like it to return something one dimensional as well, not a (nx1). So to take care of this case, I would need to add other lengthy if statements and reshaping, which would make my code look even heavier and uglier.
What's the best way out?
numpy
functions make adjustments like this all the time. Look for example atnp.atleast_2d
, or howvstack
,hstack
andcolumn_stack
expand on the basicconcatenate
. Thekeep_dims
parameter of functions likenp.sum
can be handy, as well as understanding the difference between indexing with0
, [0]` and0:1
. For some reason the transition from MATLAB tonumpy
wasn't that painful for me. – hpauljreshape
-based approach, only with anotherreshape
at the end to restore the original number of dimensions, which you would need to store initially in a variable – Luis Mendolike it to return something one dimensional as well, not a (nx1)
-.squeeze()
that extra dimension out at the end of the function. The best way out might be to just start using Numpy and get used to the way it works unless you can find another suitable package to accomplish what you want. If you are asking for package/library recommendations that is off topic at SO. – wwii