我正在处理降雨量的时间序列,希望计算单个降雨事件的长度和体积,其中“事件”是一系列非零时间步长。我正在处理多个时间序列,每个序列有大约60k个时间步长,但目前的方法速度相当慢。
目前我的方法如下:
import numpy as np
def count_events(timeseries):
start = 0
end = 0
lengths = []
volumes = []
# pad a 0 at the edges so as to include edges as "events"
for i, val in enumerate(np.pad(timeseries, pad_width = 1, mode = 'constant')):
if val > 0 and start==0:
start = i
if val == 0 and start>0:
end = i
if end - start != 1:
volumes.append(np.sum(timeseries[start:end]))
elif end - start == 1:
volumes.append(timeseries[start-1])
lengths.append(end-start)
start = 0
return np.asarray(lengths), np.asarray(volumes)
期望输出:
testrain = np.array([1,0,1,0,2,2,8,2,0,0,0.1,0,0,1])
lengths, volumes = count_events(testrain)
print lengths
[1 1 4 1 1]
print volumes
[ 1. 1. 12. 0.1 1. ] # 12 should actually be 14, my code returns wrong results.
我想到了一个更好的方法来做这件事,利用numpy的效率,但是目前还没有想到其他的方法...
编辑:
比较不同的解决方案:
testrain = np.random.normal(10,5, 60000)
testrain[testrain<0] = 0
我的解决方案(产生错误结果,不确定原因):
%timeit count_events(testrain)
#10 loops, best of 3: 129 ms per loop
@dawg的:
%timeit dawg(testrain) # using itertools
#10 loops, best of 3: 113 ms per loop
%timeit dawg2(testrain) # using pure numpy
#10 loops, best of 3: 156 ms per loop
"@DSM's:"
%timeit DSM(testrain)
#10 loops, best of 3: 28.4 ms per loop
@DanielLenz的:
%timeit DanielLenz(testrain)
#10 loops, best of 3: 316 ms per loop
np.diff
和np.where
来实现:diff 可以找到序列发生变化的点。 - user707650