Reputation: 7317
I found an interesting thing when comparing MATLAB and numpy.
MATLAB:
x = [1, 2]
n = size(X, 2)
% n = 1
Python:
x = np.array([1, 2])
n = x.shape[1]
# error
The question is: how to handle input which may be both ndarray with shape (n,) and ndarray with shape (n, m).
e.g.
def my_summation(X):
"""
X : ndarray
each column of X is an observation.
"""
# my solution for ndarray shape (n,)
# if X.ndim == 1:
# X = X.reshape((-1, 1))
num_of_sample = X.shape[1]
sum = np.zeros(X.shape[0])
for i in range(num_of_sample):
sum = sum + X[:, i]
return sum
a = np.array([[1, 2], [3, 4]])
b = np.array([1, 2])
print my_summation(a)
print my_summation(b)
My solution is forcing ndarray shape (n,) to be shape (n, 1).
The summation is used as an example. What I want is to find an elegant way to handle the possibility of matrix with only one observation(vector) and matrix with more than one observation using ndarray.
Does anyone have better solutions?
Upvotes: 0
Views: 262
Reputation: 221664
In a ndarray X
, len(X)
would the number of elements along the first axis. So, for a 2D array, it would be the number of rows and for a 1D array, it would be the number of elements in itself. This property could be used to reshape the input array that could be a 1D or a 2D array into a 2D array output. For a 1D array as input, the output 2D array would have number of rows same as number of elements. For a 2D array input case, it would have the number of rows same as before, therefore no change with it.
To sum up, one solution would be to put a reshaping code at the top of the function definition, like so -
X = X.reshape(len(X),-1)
Sample runs -
2D Case:
In [50]: X
Out[50]:
array([[6, 7, 8, 1],
[6, 2, 3, 0],
[5, 1, 8, 6]])
In [51]: X.reshape(len(X),-1)
Out[51]:
array([[6, 7, 8, 1],
[6, 2, 3, 0],
[5, 1, 8, 6]])
1D Case:
In [53]: X
Out[53]: array([2, 5, 2])
In [54]: X.reshape(len(X),-1)
Out[54]:
array([[2],
[5],
[2]])
Upvotes: 1
Reputation: 2236
I recently learned about numpy.atleast_2d
from the Python control
toolbox. You also don't need a for-loop for summation, rather use
numpy.sum
.
import numpy as np
def my_summation(X):
"""
X : ndarray
each column of X is an observation.
"""
# my solution for ndarray shape (n,)
# if X.ndim == 1:
# X = X.reshape((-1, 1))
X = np.atleast_2d(X)
return np.sum(X, axis=1)
a = np.array([[1, 2], [3, 4]])
b = np.array([1, 2])
print my_summation(a)
print my_summation(b)
gives
[3 7]
[3]
Upvotes: 1