我的时间轴存储在简单的numpy Arrays中,它们很长(> 1000万次)
我必须检测机器停机,它显示在时间向量的跳转中。关机之后,我想删除接下来的10个值(传感器在开机后会暂时给出不良结果)并继续。
我想出了以下代码:
Keep_data=np.empty_like(Timestamp_new,dtype=np.bool)
Keep_data[0]=False
Keep_data[1:]=Timestamp_new[1:]>(Timestamp_new[:-1]+min_shutdown_length)
for item in np.nonzero(np.logical_not(Keep_data))[0]:
Keep_data[item:min(item+10,len(Keep_data)]=False
Timestampnew=Timestampnew[Keep_data]
任何人都可以建议一个更有效的代码,没有纯粹的Python循环吗?
谢谢。
答案 0 :(得分:2)
基本上,您正在尝试传播/增长或使用dilate
False
区域的图像处理术语。同样,我们有一个内置的scipy's binary_dilation
。现在,您正在尝试使其从输入数组False
中的每个此类Keep_data
元素开始向更高的索引增长。因此,我们需要使用不同的偏移量(或scipy称之为:origin
)而不是默认值0
,否则每个元素的两端都会扩展。
因此,总而言之,使用它来实现摆脱代码的循环部分,我们会有这样的实现 -
N = 10 # Interval length
dilated_mask = binary_dilation(~Keep_data, structure=np.ones(N),origin=-int(N/2))
Keep_data[dilated_mask] = False
另一种方法更接近于在问题中作为循环代码发布的方法,但使用NumPy's broadcasting feature
进行矢量化,看起来像这样 -
N = 10 # Interval length
idx = np.nonzero(np.logical_not(Keep_data[:-N]))[0]
Keep_datac[(idx + np.arange(N)[:,None]).ravel()] = False
rest = np.nonzero(np.logical_not(Keep_data[-N:]))[0]
if len(rest)>0:
Keep_datac[-N+rest[0]:] = False