Ann Descomp - 2 months ago 5
Python Question

making a function that can take arguments in various shapes

Q1)
Numpy functions can take arguments in different shapes. For instance, np.sum(V) can take either of two below and return outputs with different shapes.

``````x1= np.array( [1,3] ) #(1)
x2= np.array([[[1,2],[3,4]], [[5,6],[7,8]]]) #(2)
``````

I am making my own function something like below, which adds two values in an 1D vector with the length of two and return the real number.

``````def foo(V):
return V[0]+V[1];
``````

However, this foo function can only take one 1D vector and cannot take any other shapes. It can only take x1 above as an argument but not x2. If I want to make my function work with either of two variables above(x1 and x2), or with any other shapes that has arrays with the length of 2 in their last dimension, how should I revise my foo function?

---------------------------update-----------------------------------

My original function was a hardcoded negative gaussian pdf function.

``````def nGauss(X, mu, cov):
# multivariate negative gaussian.
# mu is a vector and cov is a covariance matrix.

k = X.shape[0];
dev = X-mu
p1 = np.power( np.power(np.pi * 2, k) , -0.5);
p2 = np.power( np.linalg.det(cov)  , -0.5)
p3 = np.exp( -0.5 * np.dot( np.dot(dev.transpose(), np.linalg.inv(cov)), dev));

return -1.0 * p1 * p2 * p3;
``````

Now his function can return only one pdf value. For example, it can only take arguments like np.array([1,2]), but cannot take arguments X like np.array([[[1,2], [5,6]], [[7,8],[9,0]]]). Here my question was how to make my gaussian function takes arguments of arbitrary shapes and return the pdf value of each point maintaining the same structure, such as
`nGauss(np.array( [1,2] ), mu, cov)`
returns [ 0.000023 ], and
`nGauss(np.array([[[1,2], [5,6]], [[7,8],[9,0]]]), mu, cov)`
returns [[ 0.000023, 0000014], [0.000012, 0.000042]].

I notice that scipy function 'multivariate_normal.pdf' can do this.

Q2)
I am also having a difficulty in understanding np's basic array.

``````t1=np.array([[1,2,3], [4,5,6]])
t2=np.array([1,2,3])
t3=np.array([[1,2,3], [4,5,6],5])
``````

The shape of t1 is (2,3), and it seems legitimate in terms of matrix perspective; 2 rows and 3 columns. However, the shape of t2 is (3,), which I think has to be (3). What's the meaning of the empty space after "3,"? Also, the shape of t3 is (3,). In this case, is the meaning of the empty space that dimensions vary?

For Q1, I'm guessing you want to add the innermost dimensions of your arrays, regardless of how many dimensions the arrays have. The simplest way to do this is to use ellipsis indexing. Here's a detailed example:

``````>>> a = np.arange(24).reshape((3, 4, 2))
>>> a
array([[[ 0,  1],
[ 2,  3],
[ 4,  5],
[ 6,  7]],

[[ 8,  9],
[10, 11],
[12, 13],
[14, 15]],

[[16, 17],
[18, 19],
[20, 21],
[22, 23]]])
>>> a[..., 0]
array([[ 0,  2,  4,  6],
[ 8, 10, 12, 14],
[16, 18, 20, 22]])
>>> a[..., 1]
array([[ 1,  3,  5,  7],
[ 9, 11, 13, 15],
[17, 19, 21, 23]])
>>> a[..., 0] + a[..., 1]
array([[ 1,  5,  9, 13],
[17, 21, 25, 29],
[33, 37, 41, 45]])
``````

This works equally well for a 1D array:

``````>>> a = np.array([1, 2])
>>> a[..., 0] + a[..., 1]
3
``````

So just define `foo` as:

``````def foo(V):
return V[..., 0] + V[..., 1]
``````