2014-10-17 2 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)) 

Но я не уверен, что нужно сортировать и группировать. Любые предложения с использованием этого или любого другого метода? Благодаря!

UPDATE:

Благодаря @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

ответ

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 

Это, очевидно, расточительно алгоритм, но учитывая, что у вас есть достаточно нескольких объектов, чтобы присвоить их каждой переменной, кому это нужно? Это должно быть мертвым легко понять, и это, вероятно, более важно здесь.