繁体   English   中英

Numpy向量化2D阵列运算错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM