[英]Numpy vectorized 2d array operation error
我正在尝试将矢量化函数应用于numpy行的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
。
在这种情况下可以使用向量化函数吗? 如果是这样,怎么办? 向量化函数可以采用数组吗?还是我误解了文档?
您正在将X
的第二个轴与coeffs
的唯一轴相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.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轴上迭代, Divakar
给行。 因此,它与使用数组包装程序的列表理解基本上相同。
apply_along_axis
对于3d或更高的输入更有意义,在3d或apply_along_axis
以上的轴上进行迭代,然后将第三个轴馈入您的函数中则更为明智。
编写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
期望您的函数返回标量,但是它有一个数组。
在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
最慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.