在pylab程序中(也可能是一个matlab程序)我有一个代表距离的numpy数组:d [t]是时间t的距离(我的数据的时间跨度是len(d)时间单位) .
我感兴趣的事件是当距离低于某个阈值时,我想计算这些事件的持续时间.很容易得到一个b = d
如何在numpy数组中有效地检测那种序列?
下面是一些python代码,说明我的问题:第四个点需要很长时间才能出现(如果没有,增加数组的大小)
from pylab import *
threshold = 7
print '.'
d = 10*rand(10000000)
print '.'
b = d
print '.'
durations=[]
for i in xrange(len(b)):
if b[i] and (i==0 or not b[i-1]):
counter=1
if i>0 and b[i-1] and b[i]:
counter+=1
if (b[i-1] and not b[i]) or i==len(b)-1:
durations.append(counter)
print '.'
解决方法:
虽然不是numpy原语,但itertools函数通常非常快,所以请尝试这个(并且测量包括这个在内的各种解决方案的时间):
def runs_of_ones(bits):
for bit, group in itertools.groupby(bits):
if bit: yield sum(group)
如果确实需要列表中的值,那么当然可以使用list(runs_of_ones(bits));但也许列表理解可能会略微加快:
def runs_of_ones_list(bits):
return [sum(g) for b, g in itertools.groupby(bits) if b]
转向“numpy-native”的可能性,那么:
def runs_of_ones_array(bits):
# make sure all runs of ones are well-bounded
bounded = numpy.hstack(([0], bits, [0]))
# get 1 at run starts and -1 at run ends
difs = numpy.diff(bounded)
run_starts, = numpy.where(difs > 0)
run_ends, = numpy.where(difs < 0)
return run_ends - run_starts
再次:确保在实际的示例中针对彼此对比解决方案!
标签:python,numpy,matlab,matplotlib