Using vectorize to apply function to each row in Numpy 2d array

Viewed 1991

I have a 1000x784 matrix of data (10000 examples and 784 features) called X_valid and I'd like to apply the following function to each row in this matrix and get the numerical result:

def predict_prob(x_valid, cov, mean, prior):
    return -0.5 * (x_valid.T.dot(np.linalg.inv(cov)).dot(x_valid) + mean.T.dot(
    np.linalg.inv(cov)).dot(mean) + np.linalg.slogdet(cov)[1]) + np.log(
    prior)

(x_valid is simply a row of data). I'm using numpy's vectorize to do this with the following code:

v_predict_prob = np.vectorize(predict_prob)
scores = v_predict_prob(X_valid, covariance[num], means[num], priors[num])

(covariance[num], means[num], and priors[num] are just constants.)

However, I get the following error when running this:

File "problem_5.py", line 48, in predict_prob
return -0.5 * (x_valid.T.dot(np.linalg.inv(cov)).dot(x_valid) + mean.T.dot(np.linalg.inv(cov)).dot(mean) + np.linalg.slogdet(cov)[1]) + np.log(prior)
AttributeError: 'numpy.float64' object has no attribute 'dot'

That is, it's not passing in each row of the matrix individually. Instead, it is passing in each entry of the matrix (not what I want).

How can I alter this to get the desired behavior?

3 Answers

I know this question is a bit outdated, but I thought I would provide an answer for 2020. Since the release of numpy 1.12, there is a new optional argument, "signature", which should allow 2D array functionality in most cases. Additionally, you will want to "exclude" the constants since they will not be vectorized.

All you would need to change is:

v_predict_prob = np.vectorize(predict_prob, exclude=['cov', 'mean', 'prior'], signature='(n)->()')

This signifies that the function should expect an n-dim array and output a scalar, and cov, mean, and prior will not be vectorized.

Related