旁注:您的字典有字符串值,而不是int值。在你的例子中,你的意思可能是< =而不是<。
因此,为了更清楚地重申您的问题,您可以:
- 有点的有序列表
(x,y)
- 有一个阈值T
- 希望找到点p 的所有连续运行我,...,p j,使得端点> T,但其他点不是;即所有点在阈值线“向下和向外倾斜”的位置。 ()请注意,这样的运行可能重叠,例如,
[71,70,{71],70,71}
)
该算法将如下所示:
from itertools import *
def dippingIntervals(points, threshold=70):
yBelowThreshold = lambda i: points[i][1]<=threshold
for below,g in groupby(range(len(points)), yBelowThreshold):
if below:
interval = list(g)
start,end = interval[0],interval[-1]
if start>0 and end<len(points)-2: #modify if "open" intervals also desired
yield points[start-1 : end+2]
演示:
>>> d = [(0, 92), (11, 70), (43, 77), (44, 76), (61, 77), (64, 69), (68, 67), (84, 68), (93, 87), (108, 81), (141, 74)]
>>> pprint(list(dippingIntervals(d)))
[((0, 92), (11, 70), (43, 77)),
((61, 77), (64, 69), (68, 67), (84, 68), (93, 87))]
您可以后处理,没有什么麻烦的数据,例如把它搬进你想要的格式,修改如上所述的功能:
... yield (start,end), {xy[1] for xy in points[start-1 : end+2]}
这种方法的缺点是它不能在迭代器上工作;以下将工作的迭代器,并且是做的更“经典”的方式:
def getY(point):
return point[1]
def dippingIntervals(points, threshold=70, key=getY):
"""
Returns runs of points whose y-values dip below intervals
>>> list(dippingIntervals([71,70,74,64,64,70,71], key=lambda x:x))
[(71, [70], 74),
(74, [64, 64, 70], 71)]
"""
def match(point):
return key(point)<=threshold
lastP = None
for p in points:
if lastP==None:
lastP = p
continue
if not match(lastP) and match(p):
start = lastP
R = [p]
elif match(lastP) and match(p):
R += [p]
elif match(lastP) and not match(p):
end = p
yield start,R,end
lastP = p
示例输出使用y值<= 70,而不是y值<70 – 2012-03-08 00:31:17
谢谢!这是一个错字。 – 2012-03-08 00:36:01
好的,相应地更新了我的答案 – 2012-03-08 00:38:10