2017-02-20 20 views
-2

При использовании интеграции я получаю ValueError, но я не могу понять, почему. Вот мой упрощенный код:ValueError при определении функции лямбда в python

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 является поэлементно минимум из трех массивов. Последняя строка дает исключение:

ValueError: setting an array element with a sequence. 

Может кто-то объяснить причину ошибки и предложить альтернативный способ осуществления этой интеграции?

+0

Просто пропустите лямбда и пусть NumPy выполнит всю работу? – Divakar

+1

Выполнение только штрафа на python2 и python3, не может воспроизвести. –

+0

Мои извинения, я ошибся в строке, в которой происходит ошибка. См. Edit – splinter

ответ

1

у вас есть куча 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,) 
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,) 

Но integrate.quad вызывает Vl со скаляром, переменная интеграции rangine от 0 до pbar. Характер интеграции заключается в оценке Vl в связке точек и суммировании значений соответствующим образом.

Vl(0) производит эту ошибку, потому что это

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

Так что вам нужно изменить Vl работать со скалярным p или выполнить вашу сумму непосредственно на массиве.

Запись

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

могли хорошо осведомленный вас в разницу. Vl не работает с x отличным от глобального p. K и R являются глобальными, x является локальным для лямбда.

+0

Благодарим вас, я теперь понимаю проблему, не могли бы вы также предложить решение/альтернативу? – splinter

1

Последняя строка не дает исключения, потому что это нормально. Вы получите исключение, когда пытаетесь использовать Vl с целым числом или float вместо массива. Следующий код работает как ожидалось

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

с кодом. Если вы хотите сравнить два массива с одним номером просто создать массив только с этим номером в качестве записи, т.е.

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

Ответ на редактирование: Это довольно странно, интеграция, но если это то, что вы хочу я хотел бы сделать это с помощью определения интеграции, т.е.

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

Спасибо, после того, что вы сказали, я проверил и обнаружил, что ошибка действительно происходит в другой строке, см. Редактирование. Как бы вы изменили интеграцию, чтобы она работала? – splinter

 Смежные вопросы

  • Нет связанных вопросов^_^