如何在lambda表达式中保持某些参数不变
How to keep certain parameters unchanged in lambda expression
情况:我正在使用 scipy 来解决优化问题。由于需要许多约束,系数位于 pandas.dataframe 对象中。我正在尝试使用循环输入所有这些约束。问题出在下一个周期,参数已经改变,所以实际上只剩下on约束了。
为了更清楚地表达问题,我举个例子(在这个例子中,只给出了几个参数。但在实际情况中,可能有50多个参数)。
第一步:我使用的代码如下:
约束是 w1 + w2 * 2 >= 0; w1 * 3 + w2 * 5 >= 0
cons = []
d = {
'type': 'ineq',
'fun': ''}
a = np.array([1,2])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
a = np.array([3,5])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
cons
Step2:使用如下代码测试cons:
只是将 w 用作 [1, 1],我希望存储在 cons 中的 fun 将输出 3 和 8,但实际上是 8 和 8.
w = np.array([1,1])
for each in cons:
fun = each['fun']
print(fun(w))
任何人都可以帮助解决这个问题吗?或者只是出了点问题。
问题是你重新定义了a
。
此代码将 a
的第二个定义重命名为 b
并给出您期望的结果:
import numpy as np
cons = []
d = {
'type': 'ineq',
'fun': ''}
a = np.array([1, 2])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
b = np.array([3, 5])
d['fun'] = lambda w: b.dot(w)
cons.append(d.copy())
print(cons)
c = np.array([1, 1])
for each in cons:
fun = each['fun']
print(fun(c))
请注意,这可以解决您眼前的问题,但这并不意味着这是您要解决的问题的最佳或非常可靠的解决方案。
我想您要找的是 functools.partial
。这是您的代码,但已重写为使用 partial
:
import numpy as np
from functools import partial
def get_dot(a, w):
return a.dot(w)
cons = []
d = {
'type': 'ineq',
'fun': None
}
d['fun'] = partial(get_dot, np.array([1, 2]))
cons.append(d.copy())
d['fun'] = partial(get_dot, np.array([3, 5]))
cons.append(d.copy())
print(cons)
g = np.array([1, 1])
for each in cons:
fun = each['fun']
print(fun(g))
情况:我正在使用 scipy 来解决优化问题。由于需要许多约束,系数位于 pandas.dataframe 对象中。我正在尝试使用循环输入所有这些约束。问题出在下一个周期,参数已经改变,所以实际上只剩下on约束了。
为了更清楚地表达问题,我举个例子(在这个例子中,只给出了几个参数。但在实际情况中,可能有50多个参数)。
第一步:我使用的代码如下:
约束是 w1 + w2 * 2 >= 0; w1 * 3 + w2 * 5 >= 0
cons = []
d = {
'type': 'ineq',
'fun': ''}
a = np.array([1,2])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
a = np.array([3,5])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
cons
Step2:使用如下代码测试cons: 只是将 w 用作 [1, 1],我希望存储在 cons 中的 fun 将输出 3 和 8,但实际上是 8 和 8.
w = np.array([1,1])
for each in cons:
fun = each['fun']
print(fun(w))
任何人都可以帮助解决这个问题吗?或者只是出了点问题。
问题是你重新定义了a
。
此代码将 a
的第二个定义重命名为 b
并给出您期望的结果:
import numpy as np
cons = []
d = {
'type': 'ineq',
'fun': ''}
a = np.array([1, 2])
d['fun'] = lambda w: a.dot(w)
cons.append(d.copy())
b = np.array([3, 5])
d['fun'] = lambda w: b.dot(w)
cons.append(d.copy())
print(cons)
c = np.array([1, 1])
for each in cons:
fun = each['fun']
print(fun(c))
请注意,这可以解决您眼前的问题,但这并不意味着这是您要解决的问题的最佳或非常可靠的解决方案。
我想您要找的是 functools.partial
。这是您的代码,但已重写为使用 partial
:
import numpy as np
from functools import partial
def get_dot(a, w):
return a.dot(w)
cons = []
d = {
'type': 'ineq',
'fun': None
}
d['fun'] = partial(get_dot, np.array([1, 2]))
cons.append(d.copy())
d['fun'] = partial(get_dot, np.array([3, 5]))
cons.append(d.copy())
print(cons)
g = np.array([1, 1])
for each in cons:
fun = each['fun']
print(fun(g))