从while循环访问np.array中的值

时间:2016-05-11 12:25:56

标签: python

我有以下代码:

import math
import numpy as np
from pylab import plot, show

    def model():
        Dt = 1
        time_step = 50

        #initializing the connection weights
        w1 = 1

        #initializing parameter values for the alogistic function
        steepness_SS_a=1
        speed_SS_a=1
        threshold_SS_a=1

        WS_a=1
        SS_a=0
        new_SS_a=np.array([SS_a])
        t=0.0
        timesteps=[t]    

        while t<30.0:

            new = SS_a + speed_SS_a * (
                    (
                        (1/(1+math.exp(-steepness_SS_a * (w1 * WS_a - threshold_SS_a))))
                        -
                        (1/(1+math.exp(steepness_SS_a *threshold_SS_a)))
                    )
                    *        
                    (1+math.exp(-steepness_SS_a*threshold_SS_a))
                    -
                    SS_a
                )
            new_SS_a = np.append(new_SS_a,new)

            SS_a=new 
            t = t + Dt     


            timesteps.append(t)

        print( timesteps )
        plot(new_SS_a)
        show()        

    model()   

这是一个计算模型(我实际上有更多的变量,这是代码的简化版本),并且在一段时间内,像SS_a这样的模型的状态必须更新。现在,代码可以工作,但是我想让它变得更透明,所以你可以在某个时间步长中提取某个状态的值。 我尝试使用for循环执行此操作,并为每个时间步为每个状态提供一个索引,如下所示:

   for i in range (30)
        SS_a[i+1] = SS_a[i]+ speedfactor*(….. - SS_a(i))*Dt

,但这不起作用,因为我无法将这些值添加到列表中。 但是,我想知道我现在使用while循环的代码是否有可能提取这些值并使模型更具说明性和透明性?

现在另一种选择是使用以下格式:

    import math
    from pylab import plot, show
    def model(Dt=1, time_step = 50, w1 = 1, steepness_SS_a=1, 
              speed_SS_a=1, threshold_SS_a=1, WS_a=1, SS_a=0, 
              t=0, t_final=30):
        result = [SS_a]
        timesteps =[]
        for ti in range(t,t_final+1,Dt):
            result.append(SS_a + speed_SS_a * (
                (
                    (1/(1+math.exp(-steepness_SS_a * (w1 * WS_a -       threshold_SS_a))))
                -
                    (1/(1+math.exp(steepness_SS_a *threshold_SS_a)))
                )
                *        
                (1+math.exp(-steepness_SS_a*threshold_SS_a))
                -
                SS_a
            )) #<- put here your complicate formula 
        timesteps.append(ti)

    print(result)
    print( timesteps )  
    plot(result)
    show()

model()`

然而,结果如下:

    [0, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789, 0.3160602794142789]

但我期待价值改变。我该怎么做才能改善这个?

1 个答案:

答案 0 :(得分:0)

因为你想在列表中放入一个新值,该值取决于放在那里的先前值,你可以像在这个例子中那样做

result=[0] #we put the initial value in the list
for _ in range(30): # the _ is to signal that we don use that value
    result.append( 10 + result[-1] ) # negative indices access the element in reverse order, -1 is the last, -2 is the previous to that etc
print(result)

使用append我们在列表的末尾添加一个元素

所以在您的代码中

...
def model():
    ...
    SS_a = [0]  
    for _ in range(30):
        SS_a.append( SS_a[-1]+ speedfactor*(... - SS_a[-1])*Dt )
    ...
    plot(SS_a)
    show()

你甚至可以通过使用参数和默认值使你的模型更灵活,这样如果你想做一些改变只是改变你调用模型而不是代码的方式,例如像这样

import math
#import numpy as np 
from pylab import plot, show
def model(Dt=1, time_step = 50, w1 = 1, steepness_SS_a=1, 
          speed_SS_a=1, threshold_SS_a=1, WS_a=1, SS_a=0, 
          t=0, t_final=30):
    result = [SS_a]
    timesteps =[]
    for ti in range(t,t_final+1,Dt):
        result.append( ... ) #<- put here your complicate formula 
        timesteps.append(ti)
    print( timesteps )  
    plot(result)
    show()
    #return result  

model() 

使用所有这些默认值我们保留原始行为,如果我们只想做一个小的改动,比如运行该模型直到时间40而不是30,我们简单地将其称为model(t_final=40),你也可以放一个返回result以便稍后您可以进行其他操作,我们也可以使用doct文本来记住每件事情的简单方法,例如

def model(Dt=1, time_step = 50, w1 = 1, steepness_SS_a=1, 
          speed_SS_a=1, threshold_SS_a=1, WS_a=1, SS_a=0, 
          t=0, t_final=30):
    """This is my model of ...
       where
       Dt: ...
       time_step: ... 
       w1: ...
       steepness_SS_a: ...
       speed_SS_a: ...
       threshold_SS_a: ...
       WS_a: ...
       SS_a: ...
       t: initial time
       t_final: final time
    """
    ...

我们告诉你一个很好的消息,解释模型以及如何使用它是你在上面调用帮助help(model)

因为你有几个模型,你可以在不同的代码片段中提取每个模型的公共部分并制作更一般的版本,这样它们就可以用作乐高模块来构建你的不同模型,例如你的原始代码可以像这样打破

import math
#import numpy as np
from pylab import plot, show

def model_generator(fun, initial=0, t_ini=0, t_end=30, t_step=1 ):
    """Generator of all the values of the given function in the given
       time interval 

       fun: function of 2 arguments time and a previous value that 
            return a new value
       initial: initial value
       t_ini: initial time
       t_end: end time
       t_step: time interval"""
    yield initial
    new_value = initial
    for t in range(t_ini, t_end+1, t_step):
        new_value = fun(t, new_value)
        yield new_value

def model_plot(mod_gen):
    """plot a given model in the form of a iterable"""
    result = list( mod_gen )
    plot(result)
    show()         

def model_fun(t, SS_a, speed_SS_a=1, steepness_SS_a=1, w1=1, WS_a=1, threshold_SS_a=1  ):
    """function that represent my model of ..."""
    return SS_a + speed_SS_a * (
                (
                    (1/(1+math.exp(-steepness_SS_a * (w1 * WS_a - threshold_SS_a))))
                    -
                    (1/(1+math.exp(steepness_SS_a *threshold_SS_a)))
                )
                *        
                (1+math.exp(-steepness_SS_a*threshold_SS_a))
                -
                SS_a
            )        

def model_1():
    """original model"""
    model_plot( model_generator(model_fun) )  

def model_2():
    """original model but with speed_SS_a=2"""
    fun = lambda t,SS_a: model_fun(t, SS_a, speed_SS_a=2)
    model_plot( model_generator(fun) )

def model_3():
    """random test model """
    fun = lambda t,p: t**2
    model_plot( model_generator(fun) )    


model_1()   
model_2()
model_3()

在这一个中,复杂的公式是在一个独立的函数model_fun中提取的,因为它只需要1个必需/变量参数来工作(其他一切都是常量),model_generator做地图时间的工作到作为参数赋予它的函数的值(因为在python中,一切都是一个对象,甚至一个函数,通过这个generator函数的方式),并且该函数需要接收2个参数时间和之前的值(我包括时间,因为这对我来说更有意义,因此model_fun也接收它但被忽略)并且还处理时间内容,最后model_plot执行其名称所暗示的内容。

准备好所有部件后,我可以制作任意数量的模型,我不必重复任何事情,工作减少到只定义功能,我可以使用lambda函数来修改我在model_2中调用上一个函数的方式,或者在model_3中定义一个新函数,或者创建一个全新的函数,只要我遵循model_generator设置的规则,就像它们一样说,天空是极限(或类似的东西)。