ValueError when defining a lambda function in python

梦想的初衷 提交于 2019-12-13 10:38:17

问题


I am receiving a ValueError when using integration, but I cannot understand why. Here is my simplified code:

import numpy as np
import scipy.integrate as integrate
pbar = 1
p = np.arange(0,pbar,pbar/1000)
h = lambda p: p**2/2+p*(1-p)
Kl = lambda p: h(p) +0.02
K = Kl(p)
R = 0.5*h(p) + 0.5*h(pbar)
Vl = lambda p: np.minimum.reduce([p, K, R])
integrate.quad(Vl, 0, pbar)[0]

Vl is the element-wise minimum of the three arrays. The last line gives the exception:

ValueError: setting an array element with a sequence.

Can someone please explain the error and propose an alternative way of doing this integration?


回答1:


You have a bunch of 1000 element arrays:

In [8]: p.shape
Out[8]: (1000,)
In [9]: K.shape
Out[9]: (1000,)
In [10]: R.shape
Out[10]: (1000,)
In [11]: np.minimum.reduce([p, K, R]).shape
Out[11]: (1000,)
In [12]: Vl(p).shape
Out[12]: (1000,)
In [8]: p.shape
Out[8]: (1000,)
In [9]: K.shape
Out[9]: (1000,)
In [10]: R.shape
Out[10]: (1000,)
In [11]: np.minimum.reduce([p, K, R]).shape
Out[11]: (1000,)
In [12]: Vl(p).shape
Out[12]: (1000,)

But integrate.quad is calling Vl with a scalar, an integration variable rangine from 0 to pbar. The nature of the integration is to evaluate Vl at a bunch of points, and sum the values appropriately.

Vl(0) produces this error because it is

In [15]: np.minimum.reduce([0, K, R])    
ValueError: setting an array element with a sequence.

So you need to change Vl to work with a scalar p, or perform your sum directly on the array.

Writing

Vl = lambda x: np.minimum.reduce([x, K, R])

might have clued you into the difference. Vl does not work with x different from the global p. K and R are globals, x is local to the lambda.




回答2:


The last line doesn't give the exception because it is fine. You will get the exception, when you try to use Vl with an integer or float instead of an array. The following code runs as expected

x = np.random.randn(K.shape)
res = Vl(x)

with your code. If you want to compare the two arrays with a single number just create an array with only this number as entry, i.e.

five_array = 5*np.ones(K.shape)
res = Vl(five_array)

Answer to the edit: This is a quite strange integration, but if that is what you want I would do it by using the definition of integration, i.e.

x_int = np.linspace(0,pbar,len(K))
integral = Vl(x_int).mean()*pbar


来源:https://stackoverflow.com/questions/42342409/valueerror-when-defining-a-lambda-function-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!