我有一个干旱指数(PDSI)的年度时间序列,其值介于-4到+4之间。我试图定义干旱事件,该事件以PDSI值0以下连续两年开始,并在连续两年大于或等于0时结束。
例如,在这一系列数据中:
ts = [-2, -2, -4, 0, -1, 0, -1, 1, -2, 2, -3, -2, 3, 1, -2,
-3, -4, -3, 3, -3, -3, -3, -1, -3, 3, 3, -4, -1, -1, 0]
注意:我尝试发布图片以帮助查看问题,但我的声誉不够高
根据上述干旱定义,本系列应该有三次干旱:
1)从0年开始到11年结束(12年级和13年级为>=
0)
2)从第14年开始到第23年结束(第24年和第25年>=
0)
3)从第26年开始到系列结束时结束:第29年。尽管这次干旱没有连续两年>=
0结束,但它仍然在进行中,应该计算在内。
返回值可以是如下数组:
droughts = [[0, 11], [14, 23], [26, 29]]
这意味着排除具有两个连续PDSI值的潜在子集<1。例如,在第一个序列[0,11]中,[1,2]和[10,11]也满足低于阈值的两个连续值。规则。但是,它们应该被忽略,因为它们是更大序列的一部分。
修改
这里有一些代码可以用来定义前两个干扰,但是挂在最后一个干扰上(我认为它无限循环)。我对Python很陌生,除了代码不起作用之外,我的猜测是效率也很低。
def find_droughts (array):
answer = []
i = 0
while i < len(array):
if (array[i] < 0 and array[i+1] < 0):
if i+1 >= len(array):
i = len(array)
end = i
a.append([start, end])
break
else:
start = i
print "start = %s" %start
for j in range(i+2, len(array)-1):
if (array[j] >= 0 and array[j+1] >= 0):
end = j-1
a.append([start, end])
print 'end=%s' %end
i = j+2;
break
else:
i += 1
else:
i += 1
return answer
find_droughts(ts)
以下输出。不得不打断内核,因为它陷入了循环。
start = 0
end=11
start = 14
end=23
start = 26
start = 27
start = 27
start = 27
start = 27
....
答案 0 :(得分:0)
这样的事情怎么样:
ts = [-2, -2, -4, 0, -1, 0, -1, 1, -2, 2, -3, -2, 3, 1, -2,
-3, -4, -3, 3, -3, -3, -3, -1, -3, 3, 3, -4, -1, -1, 0]
# find positions of 2 consecutive negatives
neg = [i for i in range(len(ts)-1) if ts[i]<0 and ts[i+1] < 0]
print neg
# find locations of 2 consecutive positives + last year
pos = [i for i in range(len(ts)-1) if ts[i]>0 and ts[i+1] > 0] + [len(ts)]
print pos
# find the earliest neg for each pos
draughts = []
for p in pos:
try:
draughts.append((neg[0],p))
neg = [n for n in neg if n > p]
except IndexError:
# no more negatives left, no draught in progress
break
print draughts
输出:
[0, 1, 10, 14, 15, 16, 19, 20, 21, 22, 26, 27]
[12, 24, 30]
[(0, 12), (14, 24), (26, 30)]
有一些不合适的和边缘的情况需要熨平但整体......
这是一种替代方法,只需要一次通过ts
:
ts = [-2, -2, -4, 0, -1, 0, -1, 1, -2, 2, -3, -2, 3, 1, -2,
-3, -4, -3, 3, -3, -3, -3, -1, -3, 3, 3, -4, -1, -1, 0]
in_draught = False
draught = []
for i in range(len(ts)-1):
if in_draught and ts[i] > 0 and ts[i+1] > 0:
in_draught = False
draught.append(i)
elif not in_draught and ts[i] <0 and ts[i+1] < 0:
in_draught = True
draught.append(i)
if in_draught:
draught.append(len(ts)-1)
print [draught[i:i+2] for i in range(0,len(draught),2)]
输出:
[[0, 12], [14, 24], [26, 29]]