Python 在numpy中,序列中第一个要跨越阈值的元素,处理从不跨越阈值的序列

Python 在numpy中,序列中第一个要跨越阈值的元素,处理从不跨越阈值的序列,python,numpy,Python,Numpy,我有一个长度为T的N个时间序列的numpy数组。我想要每个时间序列第一次跨过某个阈值的索引,如果它从未跨过某个阈值,则需要-1或类似的值。取ts\u数组=np.randn(N,T) np.argmax(ts_array>cutoff,axis=1)接近,但对于在时间0处超过阈值的时间序列和从不超过阈值的时间序列,它都返回0 np.其中(…)和np.非零(…)是可能的,但是它们的返回值需要相当可怕的处理才能提取我感兴趣的向量 这个问题类似于,但没有一个答案能解决它。使用np.where也不错。我将

我有一个长度为T的N个时间序列的numpy数组。我想要每个时间序列第一次跨过某个阈值的索引,如果它从未跨过某个阈值,则需要-1或类似的值。取
ts\u数组=np.randn(N,T)

np.argmax(ts_array>cutoff,axis=1)
接近,但对于在时间0处超过阈值的时间序列和从不超过阈值的时间序列,它都返回0

np.其中(…)
np.非零(…)
是可能的,但是它们的返回值需要相当可怕的处理才能提取我感兴趣的向量


这个问题类似于,但没有一个答案能解决它。

使用
np.where
也不错。我将以下内容作为起点:

ts_array = np.random.rand(10, 10)
cutoff = 0.5

# Get a list of all indices that satisfy the condition
rows, cols = np.where(ts_array > cutoff)
if len(rows) > 0:
    index = (rows[0], cols[0])
else:
    index = -1
注意,
np.其中
返回两个数组,一个行索引列表和一个列索引列表。它们是匹配的,因此选择每个数组中的第一个将为我们提供值高于截止值的第一个实例。我没有一个很好的单行程序,但是处理代码也不太糟糕。它应该很容易适应您的情况。

一行:

(ts > c).argmax() if (ts > c).any() else -1
假设
ts=ts\u数组
c=cutoff

否则:

使用
argmax()
any()

ts\u数组
看起来像:

print ts_array, '\n'

[ 0.4449  0.4076  0.4601  0.4652  0.4627] 
各种检查:

print xover(ts_array, 0.400), '\n'

0 

print xover(ts_array, 0.460), '\n'

2 

print xover(ts_array, 0.465), '\n'

3 

print xover(ts_array, 1.000), '\n'

-1 

谢谢,但是ts_数组是一个2D结构(请参见我在问题中添加的初始化示例),因此我需要将其映射到每一行,这只会增加丑陋性,因为2D布尔数组上的(…)返回2个1D向量,指定行和列索引。解析这将是可怕的。我更改了代码以反映2D
np.where
解决方案。如果需要通过阈值的索引列表,可以使用
list(zip(np.where(ts\u array>cutoff))
。如何选择第一个实例?谢谢,但是(正如我在对SNygard的评论中提到的)ts_数组是一个2D结构,所以我需要将它映射到每一行。这是可行的,我只是希望有一个很好的矢量化单线性,但这可能根本不存在。@MHankin这是一个矢量化的解决方案。它也可以是一艘班轮。一行解决方案通常更难阅读,效率更低。例如,在我的解决方案中,我可以编写
(ts>c).argmax()if(ts>c).any()else-1
给定
ts=ts\u数组
c=cutoff
(ts>c).argmax()
按原样进行矢量化
(ts>c).any()
。我通过分配
x=ts>c
获得优势,因此我不必计算两次。我会用一行代码更新答案,但效率较低。
print xover(ts_array, 0.400), '\n'

0 

print xover(ts_array, 0.460), '\n'

2 

print xover(ts_array, 0.465), '\n'

3 

print xover(ts_array, 1.000), '\n'

-1