使用向量化将函数应用于Numpy 2D数组中的每一行

6

我有一个1000x784的数据矩阵(10000个例子和784个特征),名为X_valid,我想对该矩阵中的每一行应用以下函数,并获取数字结果:

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只是一行数据)。我正在使用numpy的vectorize来完成此操作,以下是代码:

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

(covariance[num]means[num]priors[num] 只是常数.)

然而,当我运行此代码时,会出现以下错误:

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'

也就是说,它不是逐行传递矩阵中的每一行。相反,它传递矩阵的每个条目(这不是我想要的结果)。

我该如何改变它以获得期望的行为?

3个回答

2

vectorize并不是迭代的一般替代品,它也不声称更快。它主要简化了对numpy广播功能的访问。通常情况下,您矢量化的函数将采用标量输入,而不是行或1d数组。

我认为无法配置vectorize以将数组传递给您的函数,而不是一个项。

您将x_valid描述为您想逐行评估的2d矩阵。其他术语为“常数”,您使用[num]进行选择。这些常数的形状是什么?

您的函数将许多这些术语视为2d数组:

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为2d时,x_valid.T才有意义。如果是1d,则转置不起作用。

只有当cov为2d时,np.linalg.inv(cov)才有意义。

mean.T.dot...假设mean为2d。

np.linalg.slogdet(cov)[1]假设np.linalg.slogdet(cov)拥有2个或更多的元素(或行)。

在进行迭代或“向量化”之前,需要向我们展示该函数如何使用一些真实数组。


1

1
我知道这个问题有点过时了,但我想为2020年提供一个答案。自numpy 1.12发布以来,有一个新的可选参数“signature”,它应该允许在大多数情况下使用2D数组功能。此外,您需要“排除”常量,因为它们不会被矢量化。
你只需要更改以下内容:
v_predict_prob = np.vectorize(predict_prob, exclude=['cov', 'mean', 'prior'], signature='(n)->()')

这意味着该函数应该接受一个n维数组并输出一个标量,而cov、mean和prior不会被向量化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接