Python:在 scipy.optimize.newton 中将列表作为参数传递

标签 python python-2.7 numpy scipy pythonxy

我想将列表作为参数传递给 optimize.newton .
我已经导入了一个 csv 并将每一行存储在一个数组中。代码如下:

with open('rand1.csv','rb') as f:
    array=[]
    for line in f:
        array.append(line)

现在,如果我查看 array[1] ,看起来像:'2,6,76,45,78,1\r\n'
我将一个函数定义为:
def func(a,b,c,d,e,f):
    return a*b*c-d*e-f

我正在运行牛顿方法:
res=[optimize.newton(func,5102,args=(x)) for x in array[0]]

但它给了我一个 TypeError": can only concatenate tuple (not "str") to tuple"
有人可以在这里帮助我吗?我知道元组元素必须用逗号分隔,我试过写 args=(x,)也是,但它没有工作。

最佳答案

首先,请记住,在您的代码中,array实际上不是一个 numpy 数组 - 它是一个普通的 Python list的字符串。可以通过拆分字符串并将元素转换为整数来使用此列表,如 Anmol_uppal 的回答,但将 csv 文件的内容直接转换为 nrows x 6 numpy 数组要简单得多,例如使用 np.loadtxt :

import numpy as np

data = np.loadtxt('rand1.csv', delimiter=',', dtype=np.int)
print(repr(data[0]))
# array([ 2,  6, 76, 45, 78,  1])
现在当您调用 optimize.newton , args=参数应该得到 6 个参数值的序列。您的原始代码不起作用,因为 array 中的每一行包含一个字符串,而不是 6 个数值。现在 data * 是一个 nrows x 6 数组,每行将包含 6 个数值,所以你现在可以这样做:
res = [optimize.newton(func, 5102, args=row) for row in data]
*请注意,我已将您的变量重命名为 arraydata避免与 np.array 混淆类(class)

更新
您的原始代码中还有另一个我最初没有发现的错误。查看 scipy.optimize.newton 的文档:

func : function

The function whose zero is wanted. It must be a function of a single variable of the form f(x,a,b,c...), where a,b,c... are extra arguments that can be passed in the args parameter.


x0: float

An initial estimate of the zero that should be somewhere near the actual zero.



现在看看你的函数定义:
def func(a,b,c,d,e,f):
    return a*b*c-d*e-f
func() 的第一个参数(你称之为 a )应该对应于 x 参数,那么只有 5 个额外的参数(根据你的定义是 b ... f )需要使用 args= 传递.当你尝试打电话时
optimize.newton(func, 5102, args=(422, 858, 129, 312, 79, 371))
发生的事情是 5102 被解释为 x0参数,并作为第一个参数传递给 func() . args= 中的 6 个值tuple 被视为额外参数,因此您的函数实际上总共有 7 个参数:
func(5102, 422, 858, 129, 312, 79, 371)
显然,func()被定义为接受 6 个参数,所以你会得到一个错误。解决此问题的正确方法取决于您如何解释函数的参数。 newton的目标是找到一个 x 的值,使得 f(x, a, b, c, ...) = 0。
您希望最小化 6 个参数中的哪一个 func()超过?

完整解释
一个稍微有趣的问题是,为什么当您将额外的参数作为数组(例如 args=data[0] )而不是元组传递时,您不会收到错误消息。答案有点复杂,但如果您有兴趣,请继续阅读。
如果你看看the source code for scipy.optimize.newton 您可以找到第一次调用您的函数的行:
q0 = func(*((p0,) + args))
在这种情况下 p0p1将是 x0 newton() 的参数, 和 args是一组额外的参数:
q0 = func(*((5102,) + (422, 858, 129, 312, 79, 371)))
(p0,)是一个元组,如果 args也是一个元组,然后 +运算符只需将这两个元组连接在一起:
q0 = func(*(5102, 422, 858, 129, 312, 79, 371))
最后,*解包元组以将参数传递给 func .最终调用如下所示:
q0 = func(5102, 422, 858, 129, 312, 79, 371)
这将引发错误,因为 6 参数函数有 7 个参数。然而,当 argsnp.array :
q0 = func(*(5102,) +  array([422, 858, 129, 312, 79, 371]))
+将增加值(value)p0args 中的每个元素:
q0 = func(*(5524, 5960, 5231, 5414, 5181, 5473))
因为现在只有 6 个参数转到 func()调用会成功,但是 newton会收敛到错误的答案!
我认为这在 scipy 中不是特别好的设计 - 它让我感到震惊,因为在大多数其他情况下,任何类似数组的输入都可以,包括列表、元组、数组等。公平地说,它确实在 newton 的文档中说那args=应该是一个元组,但为了安全起见,我仍然会进行类型检查或将其显式转换为元组。我可以尝试在 scipy 中解决这个问题。

关于Python:在 scipy.optimize.newton 中将列表作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28091246/

相关文章:

python - 将元素插入 numpy 数组

python - 具有服务帐户的 JWTAssertionCredentials 因 asn1 数据不足错误而失败

python - 如何在 OpenCV Python 中检测全黑图像?

Python,py.test 'HTMLReport' 对象没有属性 'execute'

python - 获取子集中元素的索引

python - 从矩阵中有效地提取重叠 block

python - 如何为 openCV SVM 格式化数据

python - 如何使用 Selenium 和 Python 绕过带有 buster 扩展的 ReCaptcha

python - 如何根据 tensorflow 中的索引张量填充值张量?

python - 在python中组合行(删除行号)以从文本文件中创建一个段落