我有一个问题,其中,在复制它与copy.deepcopy或numpy.copy后,Numpy数组中的值发生更改,实际上,如果我在复制之前先打印数组,它会得到不同的值。为什么deepcopy更改numpy数组的值?
我使用Python 3.5,numpy的1.11.1,SciPy的0.18.0
我的出发阵列包含在一个元组列表;每个元组是对:一个浮子(时间点)和numpy的阵列(一个ODE中的该时间点的溶液),例如:
[(0.0, array([ 0., ... 0.])), ...
(3.0, array([ 0., ... 0.]))]
在这种情况下,我想在最后时间点的阵列。
当我拨打以下:
tandy = c1.IntegrateColony(3)
ylast = copy.deepcopy(tandy[-1][1])
print(ylast)
我得到的东西,是对这个系统我试图模拟:
[7.14923891e-07 7.14923891e-07 ... 8.26478813e-01 8.85589634e-01]
然而,有以下:
tandy = c1.IntegrateColony(3)
print(tandy[-1][1])
ylast = copy.deepcopy(tandy[-1][1])
print(ylast)
我全部为零:
[0.00000000e+00 0.00000000e+00 ... 0.00000000e+00 0.00000000e+00]
[ 0. 0. ... 0. 0.]
我应该添加更大的系统和不同的参数,显示tandy [k] [1](使用print()或只是通过在命令行中调用它)显示所有非零值接近零,即< 1e-70,但这对系统仍然不明智。
随着:
tandy = c1.IntegrateColony(3)
ylast = np.copy(tandy[-1][1])
print(ylast)
我再次得到合理的输出:
[7.14923891e-07 7.14923891e-07 ... 8.26478813e-01 8.85589634e-01]
其使用scipy.integrate.ode产生 '坦迪' 是以下的(编辑为清楚起见)的功能,和set_solout方法来获得中间时间点的解决方案:
def IntegrateColony(self, tmax=1):
# I edited out initialization of dCdt & first_step for clarity.
y = ode(dCdt)
y.set_integrator('dopri5', first_step=dt0, nsteps=2000)
sol = []
def solout(tcurrent, ytcurrent):
sol.append((tcurrent, ytcurrent))
y.set_solout(solout)
y.set_initial_value(y=C0, t=0)
yfinal = y.integrate(tmax)
return sol
尽管I co通过返回yfinal得到最后一个时间点,我想弄清楚为什么它的行为是这样的。
感谢您的建议!
米奇
编辑: 如果我打印所有溶胶(print(tandy)
或print(IntegrateColony...
)的,它出来作为(在数组作为0与值)如上所示,即:
[(0.0, array([ 0., ... 0.])), ...
(3.0, array([ 0., ... 0.]))]
但是,如果将其复制为(y = copy.deepcopy(tandy); print(y)
),则阵列的值介于1e-7和1e + 1之间。
如果我连续两次执行print(tandy[-1][1])
,它们将填充零,但格式更改(从0.0000
到0.
)。
我在遵循LutzL和hpaulj的评论中的建议时注意到了另外一个特性:如果我在控制台(运行Spyder)中运行tandy = c1.IntegrateColony(3)
,则数组在变量浏览器中填充为零。但是,如果我运行在控制台以下:
tandy = c1.IntegrateColony(3); ylast=copy.deepcopy(tandy)
无论在坦迪和ylast阵列在我希望的范围内都充满了价值观,print(tandy[-1][1])
现在给:
[7.14923891e-07 7.14923891e-07 ... 8.26478813e-01 8.85589634e-01]
即使如果我找到能够阻止这种行为的解决方案,我会很感激任何人对于发生了什么事情的洞察力,所以我不会再犯同样的错误。
谢谢!
编辑: 这里有一个简单的例子,让这种行为:
import numpy as np
from scipy.integrate import ode
def testODEint(tmax=1):
C0 = np.ones((3,))
# C0 = 1 # This seems to behave the same
def dCdt_simpleinputs(t, C):
return C
y = ode(dCdt_simpleinputs)
y.set_integrator('dopri5')
sol = []
def solout(tcurrent, ytcurrent):
sol.append((tcurrent, ytcurrent)) # Behaves oddly
# sol.append((tcurrent, ytcurrent.copy())) # LutzL's idea: Works
y.set_solout(solout)
y.set_initial_value(y=C0, t=0)
yfinal = y.integrate(tmax)
return sol
tandy = testODEint(1)
ylast = np.copy(tandy[-1][1])
print(ylast) # Expect same values as tandy[-1][1] below
tandy = testODEint(1)
tandy[-1][1]
print(tandy[-1][1]) # Expect same values as ylast above
当我运行它,我得到以下输出ylast
和tandy[-1][1]
:
[ 2.71828196 2.71828196 2.71828196]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00]
代码当我遇到这个问题时,我一直在努力工作是一个令人尴尬的混乱,但如果你想看看,旧版本在这里:https://github.com/mvondassow/BryozoanModel2
如果你打印所有的sol,行是否改变或者都是一样的?您可能必须使用'sol.append((tcurrent,ytcurrent.copy()))'来避免始终存储与积分器状态向量相同的指针。 – LutzL
当你知道对象是一个数组时,不要打扰'deepcopy'。 'x.copy()'就足够了。但我觉得'tandy'有一些有趣的东西。这不仅仅是一个独立价值清单。当你连续两次打印(tandy [-1] [1])时会发生什么? – hpaulj
我会试试LutzL。 –