在前面元素的状态很重要的情况下,基于numpy时间的矢量运算-for循环合适吗?

tnt*_*tnt 5 python numpy

当执行状态很重要的基于时间的计算时,numpy数组提供了什么。换句话说,序列中较早或较晚发生的情况很重要。

考虑以下基于时间的向量,

TIME = np.array([0.,   10.,  20.,  30.,  40.,  50.,  60.,  70.,  80.,  90.])
FLOW = np.array([100., 75.,  60.,  20.0, 60.0, 50.0, 20.0, 30.0, 20.0, 10.0])
TEMP = np.array([300., 310., 305., 300., 310., 305., 310., 305., 300., 295.0])
Run Code Online (Sandbox Code Playgroud)

假设一旦FLOW降到30以下,而不是再次升高到50以上,就应该应用TEMP的指数衰减。在上面的数据中,将在TIME = 60处应用一个函数,并以此更新TEMP的最后两个值次要功能将从相应的TEMP值开始。

需要“向前看”以确定在请求<30条件后,元件中的FLOW是否上升到50以上。似乎numpy函数不是针对状态重要的基于时间的向量,而嵌套for循环的传统方法也许仍然是要走的路。但是考虑到我对numpy的新颖性以及我必须执行这些类型的基于状态的操作的事实,我将对指导或肯定表示赞赏。

Gab*_*ant 4

虽然乔·金顿的答案当然是正确的(而且相当灵活),但它比需要的更加迂回。对于尝试学习 Numpy 的人来说,我认为更直接的路线可能更容易理解。

正如我在您的问题下指出的那样(乔也注意到了),您对代码行为的描述与示例之间似乎存在不一致。像乔一样,我也假设您描述了正确的行为。

一些注意事项:

  1. Numpy 与过滤器数组配合得很好,可以指定应将操作应用于哪些元素。我多次使用它们。
  2. np.flatnonzero函数返回一个索引数组,指定给定数组非零(或 True)的位置。

该代码使用您提供的示例数组。

import numpy as np

TIME = np.array([0.,   10.,  20.,  30.,  40.,  50.,  60.,  70.,  80.,  90.])
FLOW = np.array([100., 75.,  60.,  20.0, 60.0, 50.0, 20.0, 30.0, 20.0, 10.0])
TEMP = np.array([300., 310., 305., 300., 310., 305., 310., 305., 300., 295.0])

last_high_flow_index = np.flatnonzero(FLOW > 50)[-1]
low_flow_indices = np.flatnonzero(FLOW < 30)
acceptable_low_flow_indices = low_flow_indices[low_flow_indices > last_high_flow_index]
apply_after_index = acceptable_low_flow_indices[0]
Run Code Online (Sandbox Code Playgroud)

现在我们有了索引,之后函数应应用于 TEMP。如果我正确地阅读你的问题,你希望一旦满足你的条件,温度就开始下降。这可以按如下方式完成:

time_delta = TIME[apply_after_index:] - TIME[apply_after_index]
TEMP[apply_after_index:] = TEMP[apply_after_index:] * np.exp(-0.05 * time_delta)
Run Code Online (Sandbox Code Playgroud)

TEMP已更新,因此print TEMP输出

[ 300.          310.          305.          300.          310.          305.
  310.          184.99185121  110.36383235   65.82339724]
Run Code Online (Sandbox Code Playgroud)

或者,您可以通过首先对函数进行向量化,将任意 Python 函数应用于适当的元素:

def myfunc(x):
    ''' a normal python function that acts on individual numbers'''
    return x + 3

myfunc_v = np.vectorize(myfunc)
Run Code Online (Sandbox Code Playgroud)

然后更新 TEMP 数组:

TEMP[apply_after:] = myfunc_v(TEMP[apply_after:])
Run Code Online (Sandbox Code Playgroud)