首先,请记住,在您的代码中,array
它实际上不是一个 numpy 数组 - 它是一个普通list
的 Python 字符串。可以通过拆分字符串并将元素转换为整数来使用此列表,如 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]
*请注意,我已重命名您的变量array
以data
避免与np.array
类混淆
更新
您的原始代码中还有另一个我最初没有发现的错误。查看以下文档scipy.optimize.newton
:
函数:函数
想要零的函数。它必须是f(x,a,b,c...) 形式的单个变量的函数,其中 a,b,c... 是可以在 args 参数中传递的额外参数。
x0:浮动
零的初始估计应该在实际零附近的某个地方。
现在看看你的函数定义:
def func(a,b,c,d,e,f):
return a*b*c-d*e-f
(您调用的)的第一个参数应该对应于x参数,然后只有5 个额外的参数(根据您的定义)需要使用. 当你尝试打电话时func()
a
b ... f
args=
optimize.newton(func, 5102, args=(422, 858, 129, 312, 79, 371))
发生的情况是 5102 被解释为x0
参数,并作为第一个参数传递给func()
. 元组中的6 个值args=
被视为额外参数,因此您的函数实际上总共获得7 个参数:
func(5102, 422, 858, 129, 312, 79, 371)
显然,func()
被定义为接受 6 个参数,所以你会得到一个错误。解决此问题的正确方法取决于您如何解释函数的参数。的目标newton
是找到x的值,使得f(x, a, b, c, ...) = 0。
您希望最小化 6 个参数中的哪一个func()
?
完整解释
一个稍微有趣的问题是,为什么当您将额外的参数作为数组(例如args=data[0]
)而不是元组传递时,您不会收到错误消息。答案有点复杂,但如果您有兴趣,请继续阅读。
如果您查看源代码,scipy.optimize.newton
您可以找到第一次调用函数的行:
q0 = func(*((p0,) + args))
在这种情况下p0
, andp1
将是 , 的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 个参数。但是,什么时候args
是np.array
:
q0 = func(*(5102,) + array([422, 858, 129, 312, 79, 371]))
+
将为中的每个元素添加值:p0
args
q0 = func(*(5524, 5960, 5231, 5414, 5181, 5473))
由于现在只有6 个参数func()
调用会成功,但newton
会收敛到错误的答案!
我认为这在 scipy 中不是特别好的设计 - 它让我感到震惊,因为在大多数其他情况下,任何类似数组的输入都可以,包括列表、元组、数组等。公平地说,它确实在文档中newton
说args=
应该是一个元组,但为了安全起见,我仍然会进行类型检查或将其显式转换为元组。我可以尝试在 scipy 中解决这个问题。