我正试图在n-row行中的2-d数组上应用矢量化函数,我遇到了ValueError: setting an array element with a sequence.
import numpy as np
X = np.array([[0, 1], [2, 2], [3, 0]], dtype=float)
coeffs = np.array([1, 1], dtype=float)
np.apply_along_axis(
np.vectorize(lambda row: 1.0 / (1.0 + np.exp(-coeffs.dot(row)))),
0, X
)
我不完全知道如何解释这个错误。我如何设置一个带序列的数组元素?
当我在一行上测试lambda函数时,它可以工作并返回一个浮点数。不知怎的,它在这个向量化函数的范围内失败了,这让我相信向量化函数是错误的,或者我没有正确使用apply_along_axis
。
在这种情况下是否可以使用矢量化函数?如果是这样,怎么样?矢量化函数可以采用数组还是我误解了文档?
答案 0 :(得分:2)
您将X
的第二个轴与coeffs
的唯一轴相减。因此,您只需将np.dot(X,coeffs)
用于sum-reductions
。
因此,矢量化解决方案将是 -
1.0 / (1.0 + np.exp(-X.dot(coeffs)))
示例运行 -
In [227]: X = np.array([[0, 1], [2, 2], [3, 0]], dtype=float)
...: coeffs = np.array([1, 1], dtype=float)
...:
# Using list comprehension
In [228]: [1.0 / (1.0 + np.exp(-coeffs.dot(x))) for x in X]
Out[228]: [0.7310585786300049, 0.98201379003790845, 0.95257412682243336]
# Using proposed method
In [229]: 1.0 / (1.0 + np.exp(-X.dot(coeffs)))
Out[229]: array([ 0.73105858, 0.98201379, 0.95257413])
使用np.apply_along_axis
的正确方法是删除np.vectorize
并沿X
的第二轴应用它,即X
的每一行 -
np.apply_along_axis(lambda row: 1.0 / (1.0 + np.exp(-coeffs.dot(row))), 1,X)
答案 1 :(得分:0)
在v 1.12 vectorize
文档中说:
默认情况下,
pyfunc
是 假设将标量作为输入和输出。
在你的尝试中:
np.apply_along_axis(
np.vectorize(lambda row: 1.0 / (1.0 + np.exp(-coeffs.dot(row)))),
0, X
)
apply_along_axis
遍历除0
之外的所有轴,并将生成的1d数组提供给其函数。因此对于2d,它将在1轴上迭代,并且为另一个轴提供。 Divakar
显示它在0轴上迭代,并提供行。所以它与使用数组包装器的列表理解基本相同。
apply_along_axis
使用3d或更高的输入更有意义,在2轴上迭代并将第三轴输入到您的函数中更为繁琐。
将lambda编写为函数:
def foo(row):
return 1.0/(1.0+np.exp(-coeffs.dot(row)))
给定一个数组(行),它返回一个标量:
In [768]: foo(X[0,:])
Out[768]: 0.7310585786300049
但是给定一个标量,它返回一个数组:
In [769]: foo(X[0,0])
Out[769]: array([ 0.5, 0.5])
这解释了sequence
错误消息。 vectorize
期望你的函数返回一个标量,但它有一个数组。
在v 1.12 vectorize
中添加了signature
参数,这样我们就可以向函数提供大于标量的内容。我在以下方面进行了探讨:
https://stackoverflow.com/a/44752552/901925
使用signature
我可以使用vectorize
:
In [784]: f = np.vectorize(foo, signature='(n)->()')
In [785]: f(X)
Out[785]: array([ 0.73105858, 0.98201379, 0.95257413])
与此相同:
In [787]: np.apply_along_axis(foo,1,X)
Out[787]: array([ 0.73105858, 0.98201379, 0.95257413])
In [788]: timeit np.apply_along_axis(foo,1,X)
10000 loops, best of 3: 80.8 µs per loop
In [789]: timeit f(X)
1000 loops, best of 3: 181 µs per loop
In [790]: np.array([foo(x) for x in X])
Out[790]: array([ 0.73105858, 0.98201379, 0.95257413])
In [791]: timeit np.array([foo(x) for x in X])
10000 loops, best of 3: 22.1 µs per loop
列表理解最快,vectorize
最慢。