【问题标题】:Python updating numpy array: type error numpy.int32 is not iterablePython 更新 numpy 数组:类型错误 numpy.int32 不可迭代
【发布时间】:2020-05-11 10:42:54
【问题描述】:

我编写了一个函数和 while 循环,旨在模拟以下化学反应系统:

系统中的化学方程式:

E + S --> ES == 1E + 1S + 0ES + 0P --> 0E + 0S + 1ES + 0P

ES --> E + S == 0E + 0S + 1ES + 0P --> 1E + 1S + 0ES + 0P

ES --> E + P == 0E + 0S + 1ES + 0P --> 1E + 0S + 0ES + 1P

系统使用以下数组表示: 酶、底物、酶-底物复合物、产品的离散种群数(时间= 0):

popul_num = np.array([200, 100, 0, 0])

反应物比例:

LHS = np.array([[1,1,0,0], [0,0,1,0], [0,0,1,0]])

产品比例:

RHS = np.matrix([[0,0,1,0], [1,1,0,0], [1,0,0,1]])

体系中三种反应的速率:

stoch_rate = np.array([0.0016, 0.0001, 0.1])

状态变化数组:

state_change_array = RHS - LHS

最大模拟时间: tmax = 20

以及模拟的开始时间: 道 = 0.0

然后我有以下函数和 while 循环来计算在上述反应过程中 popul_num 中分子的离散数量如何随时间变化。

在反应运行一段时间后,popul_num 数组会更新为新值:

def propensity_calc(LHS, popul_num, stoch_rate):
propensity = np.zeros(len(LHS))
for row in range(len(LHS)):
        a = stoch_rate[row]     # type = numpy.float64
        for i in range(len(popul_num)):
            if (popul_num[i] >= LHS[row, i]):       
                binom_rxn = binom(popul_num[i], LHS[row, i])
                a = a*binom_rxn
            else:
                a = 0
                break
        propensity[row] = a     # type = numpy.ndarray
return propensity

propensity = np.zeros(len(LHS))
while tao < tmax:
  propensity = propensity_calc(LHS, popul_num, stoch_rate)
  a0 = (sum(propensity))
  if a0 == 0.0:
      break
  t = np.random.exponential(1/a0)
  rxn_probability = propensity / a0   # propensity = array a0 = number --> Error
  num_rxn = np.arange(rxn_probability.size)
  if tao + t > tmax:
      tao = tmax
      break
  j = stats.rv_discrete(values=(num_rxn, rxn_probability)).rvs()
  print(tao, t)
  tao = tao + t
  popul_num = popul_num + np.squeeze(np.asarray(state_change_array[j]))

我想使用 matplotlib 在折线图上为 popul_num 中的每个物种绘制一条单独的线,以显示它们随时间变化的数量。

我尝试将每个新值附加到 popul_num 并使用 numpy.append() 绘制新数组,但没有任何运气。

我尝试编写一个循环来遍历数组的每个元素,如下所示:

for i in range(4):
plt.plot(list(enumerate(popul_num[i])))  # error numpy.int32 object is not iterable
plt.show()

但我收到以下错误: TypeError: 'numpy.int32' 对象不可迭代

是否有解决这个问题的方法或不同的方法来为每个物种随着时间的推移创建一个 popul_num 图?

编辑: 目前这是代码正在生成的情节

这是想要的绘图类型,但我希望 popul_num 数组的每个元素都有一条单独的线,显示该分子种类随时间的变化。

干杯

【问题讨论】:

    标签: python arrays numpy matplotlib


    【解决方案1】:

    popul_num 是在每个步骤中被覆盖的 4 个值。要绘制曲线,您需要将所有这些值保存在单独的数组中。以下代码显示了一个示例:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.special import binom
    from scipy import stats
    
    popul_num = np.array([200, 100, 0, 0])
    
    LHS = np.array([[1, 1, 0, 0], [0, 0, 1, 0], [0, 0, 1, 0]])
    RHS = np.array([[0, 0, 1, 0], [1, 1, 0, 0], [1, 0, 0, 1]])
    stoch_rate = np.array([0.0016, 0.0001, 0.1])
    state_change_array = RHS - LHS
    
    def propensity_calc(LHS, popul_num, stoch_rate):
        propensity = np.zeros(len(LHS))
        for row in range(len(LHS)):
            a = stoch_rate[row]  # type = numpy.float64
            for i in range(len(popul_num)):
                if (popul_num[i] >= LHS[row, i]):
                    binom_rxn = binom(popul_num[i], LHS[row, i])
                    a = a * binom_rxn
                else:
                    a = 0
                    break
            propensity[row] = a  # type = numpy.ndarray
        return propensity
    
    tmax = 20
    tao = 0.0
    
    popul_num_all = [popul_num]
    
    propensity = np.zeros(len(LHS))
    while tao < tmax:
        propensity = propensity_calc(LHS, popul_num, stoch_rate)
        a0 = (sum(propensity))
        if a0 == 0.0:
            break
        t = np.random.exponential(1 / a0)
        rxn_probability = propensity / a0  # propensity = array a0 = number --> Error
        num_rxn = np.arange(rxn_probability.size)
        if tao + t > tmax:
            tao = tmax
            break
        j = stats.rv_discrete(values=(num_rxn, rxn_probability)).rvs()
        print(tao, t)
        tao = tao + t
        popul_num = popul_num + np.squeeze(np.asarray(state_change_array[j]))
        popul_num_all.append(popul_num)
    
    popul_num_all = np.array(popul_num_all)
    for i, (label, color) in enumerate(zip(['Enzyme', 'Substrate', 'Enzyme-Substrate complex', 'Product'],
                                           ['limegreen', 'dodgerblue', 'orange', 'crimson'])):
        plt.plot(popul_num_all[:, i], label=label, color=color)
    plt.legend()
    plt.tight_layout()
    plt.show()
    

    每条曲线的名称都会添加一个图例。

    【讨论】:

      【解决方案2】:

      您正在尝试枚举整数 popul_num[i],因此引发了错误。你的意思是这个而不是你的 for 循环:

      plt.plot(popul_num)
      plt.show()
      

      【讨论】:

      • 我试过了,但它只返回一个单线图,我认为它绘制了 (0,200)、(1, 100)、(2, 0) 和 (3,0)
      • @Mike5298 是的。那你想要什么样的情节?点图? popul_num 是一维数字数组,对吧?你想如何绘制这些数字。
      • 那么应该把popul_num改成二维数组吗?
      • 嗯,这取决于你想要做什么。也许详细说明你想要popul_num 的形状以及你想从popul_num 得到什么数字。如果上面的解决方案回答了你,我可以删除这个帖子。
      猜你喜欢
      • 2020-03-08
      • 1970-01-01
      • 2021-10-28
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      • 2021-02-13
      • 2022-11-29
      相关资源
      最近更新 更多