2014-10-17 46 views
1

我有一個列表,我想將其放入重疊值的組中。我的直覺是使用itertools.groupby,但我不知道如何使它工作。組重疊數組

某些樣本數據:

a = np.array(range(10)) 
b = np.array(range(90,100)) 
c = np.array(range(50,60)) 
d = np.array(range(8,15)) 
e = np.array(range(55,80)) 

我想與三組重疊的(或不連續的)陣列落得:

groups = [[a,d],[b],[c,e]] 

可否使用itertools.groupby要這樣做嗎?

for k,g in itertools.groupby([a,b,c,d,e], lambda x: SOMETHING?): 
    groups.append(list(g)) 

但我不確定按什麼排序和分組。任何建議使用這個或任何其他方法?謝謝!

更新:

感謝@abarnert下面的解決方案。你說得對,它不是一個巨大的數組,所以迭代強力工作正常。

arrays, groups, idx = [a,b,c,d,e], [], [] 
for N,X in enumerate(arrays): 
    if N not in idx: 
    group, idx = [X], idx+[N] 
    for n,x in enumerate(arrays): 
     if n not in idx and any(np.where(np.logical_and(X<x[-1],X>x[0]))[0]): group.append(x), idx.append(n) 
    groups.append(group) 
+0

有效的區間排序實際上是一個開放的研究問題;這是一個二次方案嗎? (對於5個區間,顯然是......) – abarnert 2014-10-17 20:59:45

回答

0

如果你的範圍列表足夠小,你可以做到這一點通過蠻力:我也有一些笨重的列表內涵做了檢查互相範圍重疊的範圍內,「合併」他們每當你找到一個循環時就開始循環。

這是一個有點笨拙與numpy的陣列來寫,所以讓我們使用(Python 3中)範圍內的對象只是爲了讓對面的想法:

def merge(x, y): 
    return range(min(x.start, y.start), max(x.stop, y.stop)) 

def overlap(x, y): 
    return x.start in y or y.start in x 

groups = {a: {a}, b: {b}, c: {c}, d: {d}, e: {e}} 

while True: 
    for key, value in groups.items(): 
     for otherkey, othervalue in groups.items(): 
      if key is otherkey: 
       continue 
      if overlap(key, otherkey): 
       del groups[otherkey] 
       del groups[key] 
       groups[merge(key, otherkey)] = value | othervalue 
       break 
     else: 
      continue 
     break 
    else: 
     break 

這顯然是一個浪費的算法,但考慮到你有沒有足夠的對象將它們分配給一個變量,誰在乎?它應該很容易理解,這在這裏可能更重要。