我遇到的问题是,在使用copy.deepcopy或numpy.copy复制Numpy数组后,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]
生成' tandy'是以下(为清晰起见编辑),它使用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
虽然我可以通过返回yfinal得到最后一个时间点,但是我想知道为什么它的行为方式就是全部时间。
感谢您的建议!
米奇
编辑:
如果我打印所有sol(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评论中的建议时注意到的另一个功能是:如果我在控制台中运行tandy = c1.IntegrateColony(3)
(运行Spyder),则数组中的零填充为零变量探险家。但是,如果我在控制台中运行以下命令:
tandy = c1.IntegrateColony(3); ylast=copy.deepcopy(tandy)
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
答案 0 :(得分:1)
发生这种情况的详细信息与ytcurrent
中处理integrate
的方式有关。但是在Python中存在各种上下文,其中列表的所有值最终都相同 - 与预期相反。
例如:
In [159]: x
Out[159]: [0, 1, 2]
In [160]: x=[]
In [161]: y=np.array([1,2,3])
In [162]: for i in range(3):
...: y += i
...: x.append(y)
In [163]: x
Out[163]: [array([4, 5, 6]), array([4, 5, 6]), array([4, 5, 6])]
x
的所有元素都具有相同的值 - 因为它们都是指向同一y
的指针,因此显示其最终值。
但如果我在将y
附加到列表之前复制In [164]: x=[]
In [165]: for i in range(3):
...: y += i
...: x.append(y.copy())
In [166]: x
Out[166]: [array([4, 5, 6]), array([5, 6, 7]), array([7, 8, 9])]
In [167]:
,我会看到更改。
print
现在,这并不能解释为什么solout
语句会更改值。但整个scipy
回调机制有点模糊。我想知道import React from 'react';
import { MuiThemeProvider} from 'material-ui';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui';
// properties of TableHeader component
let headerProps = {
enableSelectAll: false,
displaySelectAll: false,
adjustForCheckbox: false
};
// initial set of rows, simulating data from the database
let rows = [
{firstName: "Adrian", favColor: "gold", uniqueId: 0 },
{firstName: "Alma", favColor: "green", uniqueId: 1 },
{firstName: "Conny", favColor: "black", uniqueId: 2 },
{firstName: "Jane", favColor: "blue", uniqueId: 3 }
];
// our table hader information, key is the name of the
// property to sort by when the header is clicked
let headers = [
{name: "First Name", key: "firstName"},
{name: "Favorite Color", key: "favColor"}
];
// our table component that can sort columns
class SortableTable extends React.Component {
constructor(props){
super(props);
this.state = {rows, sortBy: 'firstName'};
}
renderHeaders(){
let header= headers.map( (h) => {
return <SortableHeader
key={h.key}
name={h.name}
onClicked={()=>this.updateSortBy(h.key)}
isSortColumn={this.state.sortBy == h.key}/>
});
return <TableRow>{header}</TableRow>;
}
renderRows() {
return this.state.rows.map( (row, i) => <UserRow {...row} key={row.uniqueId}/> );
}
updateSortBy(sortBy){
// multiple clicks on the same column reverse the sort order
if( sortBy == this.state.sortBy ){
this.setState( {rows: [...this.state.rows.reverse()]} );
return;
}
let rows = [...this.state.rows];
rows.sort( (a,b) => {
if (a[sortBy] < b[sortBy])
return -1;
if(a[sortBy] > b[sortBy])
return 1;
return 0;
});
this.setState({rows, sortBy});
}
render() {
return (
<MuiThemeProvider>
<Table>
<TableHeader {...headerProps}>
{this.renderHeaders()}
</TableHeader>
<TableBody>
{this.renderRows()}
</TableBody>
</Table>
</MuiThemeProvider>
);
}
}
function SortableHeader(props){
let style = {
cursor: "pointer"
}
if(props.isSortColumn){
style.fontWeight = "bold";
style.color = "black";
}
return (
<TableHeaderColumn>
<div style={style} onClick={() => props.onClicked()}>{props.name}</div>
</TableHeaderColumn>
);
}
function UserRow(props){
return (
<TableRow>
<TableRowColumn>{props.firstName}</TableRowColumn>
<TableRowColumn>{props.favColor}</TableRowColumn>
</TableRow>
);
}
export default SortableTable;
中是否有关于定义此类回调的陷阱的警告?