首页 > 解决方案 > TypeError:只有大小为 1 的数组可以转换为 Python 标量在一个简单程序中到达

问题描述

当我尝试这段代码时,

from math import exp
import numpy as np

w1=2
b1=0.5
b2=0.75

X=[[0, 1, 1, 1], [1, 1, 1, 1]]
y=(np.dot(w1,X)-b1)
tanh=np.vectorize((1-exp(-2*y))/(1+exp(-2*y)))
y_out=1/(1+np.exp(-tanh))-b2 

print(y_out)

我收到了这个错误:

TypeError:只有 size-1 的数组可以转换为 Python 标量。

我在哪里犯错?

标签: pythonnumpy

解决方案


In [269]: import math                                                           
In [270]: w1=2 
     ...: b1=0.5 
     ...: b2=0.75 
     ...: X=[[0, 1, 1, 1], [1, 1, 1, 1]] 
     ...: y=(np.dot(w1,X)-b1)                                                   
In [271]: X                                                                     
Out[271]: [[0, 1, 1, 1], [1, 1, 1, 1]]
In [273]: y                                                                     
Out[273]: 
array([[-0.5,  1.5,  1.5,  1.5],
       [ 1.5,  1.5,  1.5,  1.5]])

Pythonnp.vectorize在调用vectorize. 它应该是一个函数,但是你写的是一个表达式。

错误出现在:

In [274]: math.exp(-2*y)                                                        
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-274-02e40bf10b29> in <module>
----> 1 math.exp(-2*y)

TypeError: only size-1 arrays can be converted to Python scalars

y是一个数组;math.exp仅适用于标量值。 np.exp适用于数组:

In [275]: np.exp(-2*y)                                                          
Out[275]: 
array([[2.71828183, 0.04978707, 0.04978707, 0.04978707],
       [0.04978707, 0.04978707, 0.04978707, 0.04978707]])

有一个lambda vectorize作品:

In [276]: fn = np.vectorize( lambda z: (1-math.exp(-2*z))/(1+math.exp(-2*z)))   
In [277]: fn(y)                                                                 
Out[277]: 
array([[-0.46211716,  0.90514825,  0.90514825,  0.90514825],
       [ 0.90514825,  0.90514825,  0.90514825,  0.90514825]])

vectorize遍历y,并将一个元素(一次一个)传递给lambdaas z

但这更快:

In [278]: (1-np.exp(-2*y))/(1+np.exp(-2*y))                                     
Out[278]: 
array([[-0.46211716,  0.90514825,  0.90514825,  0.90514825],
       [ 0.90514825,  0.90514825,  0.90514825,  0.90514825]])

vectorize本质上是这个列表理解的一个变体:

In [280]: [ (1-math.exp(-2*z))/(1+math.exp(-2*z)) for z in y.ravel()]           
Out[280]: 
[-0.46211715726000974,
 0.9051482536448665,
 0.9051482536448665,
 0.9051482536448665,
 0.9051482536448665,
 0.9051482536448665,
 0.9051482536448665,
 0.9051482536448665]

推荐阅读