[英]Puzzling a covered region from list of subregions
我有一長串的值x和y,並按x值的值排序。 我想輸出一個最長連續范圍的x和y值的列表。 說起來有點困難,但是希望通過以下示例可以使它變得清楚:
0, 148
0, 145
0, 186
0, 5768
600, 2374
2376, 2415
3000, 4315
6000, 6616
6000, 6799
6000, 7262
由於任何條目均未覆蓋5768和6000之間的區域,因此以上內容應輸出:
0, 5768
6000, 7262
在我看來,這似乎應該是一個簡單的問題,但是我一直在解決它一段時間。 我已經在下面發布了我的代碼。 我目前的工作問題是,在對x值進行排序的同時,第k行的x值可能超過第k-1行的y值,但沒有標記新的連續字符串的開始。
lines = [line.strip('\n') for line in open('test')]
myarray=[]
for line in lines:
myarray.append(line.split(', '))
def findCoveredRegions(regionArray):
resultsContigs = []
j = regionArray[0][1]
i = regionArray[0][0]
for line in regionArray:
last_i = i
i = line[0]
if i <= j:
if line[1] > j:
j = line[1]
else:
resultsContigs.append([last_i,j])
resultsContigs.append([i,regionArray[len(regionArray)-1][1]])
return resultsContigs
print findCoveredRegions(myarray)
這是一個numpy的解決方案
myarray = np.asanyarray(myarray)
order = np.argsort(myarray.ravel())
coverage = np.add.accumulate(1 - 2*(order%2))
gaps = np.where(coverage==0)[0]
left = order[np.r_[0, gaps[:-1] + 1]]
right = order[gaps]
result = myarray.ravel()[np.c_[left, right]]
它匯集並排序所有邊界。 然后從左到右計數遇到的左(+1)和右(-1)個邊界。 這個數字永遠不會為負,只有在存在差距的地方才降至零。 從間隙的位置重建覆蓋的間隔。
這不會特別快,但是我認為它相當Python且可讀。 它不需要或使用間隔的排序列表。
intervals = [(0, 148),
(0, 145),
(0, 186),
(0, 5768),
(600, 2374),
(2376, 2415),
(3000, 4315),
(6000, 6616),
(6000, 6799),
(6000, 7262)]
def intersect(interval_a, interval_b):
"""Return whether two intervals intersect"""
(a_bottom, a_top), (b_bottom, b_top) = interval_a, interval_b
return a_bottom <= b_top and b_bottom <= a_top
def union_one_one(interval_a, interval_b):
"""Return the union of two intervals"""
(a_bottom, a_top), (b_bottom, b_top) = interval_a, interval_b
return min(a_bottom, b_bottom), max(a_top, b_top)
def union_many_one(old_intervals, new_interval):
"""Return the union of a new interval with several old intervals."""
result = []
for old_interval in old_intervals:
# If an old interval intersects with the new interval, merge the old interval into the new one.
if intersect(old_interval, new_interval):
new_interval = union_one_one(old_interval, new_interval)
# Otherwise, leave the old interval alone.
else:
result.append(old_interval)
result.append(new_interval)
return result
def union_all(intervals):
"""Return the union of a collection of intervals"""
result = []
for interval in intervals:
result = union_many_one(result, interval)
return result
print(union_all(intervals))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.