2015-05-01 5 views
1

У меня есть 2 массива с координатами сетки.найти соседей в np массиве в python

[402, 401, 356, 355, 356, 355, 356, 386, 354, 355, 356, 386, 354, 355, 386, 354, 287, 288, 289, 290, 291, 292, 287, 288, 290, 291, 292, 293, 292, 293, 294, 295, 293, 294, 295, 296, 294, 295, 296, 146, 145, 146, 167, 168, 162, 163, 164, 165, 166, 167, 168, 169, 170, 160, 161, 162, 165, 166, 167, 168, 169, 170, 162, 163, 166, 167, 168, 169, 170, 163, 167, 168, 169, 170, 168, 169, 169, 170, 170, 310, 310, 311, 312, 313, 314, 315, 316, 317, 311, 312, 313, 314, 315, 316, 317, 311, 312, 313, 314, 315, 316, 311, 312, 313, 314, 315, 316, 311, 312, 313, 314, 274, 275, 275, 274, 275, 274, 275, 273, 274, 275, 274, 275, 274, 272, 273, 272, 273, 272, 273, 272, 273, 272, 273, 271, 272, 271] 
[242, 243, 257, 258, 258, 259, 259, 259, 260, 260, 260, 260, 261, 261, 261, 262, 284, 284, 284, 284, 284, 284, 285, 285, 285, 285, 285, 285, 286, 286, 286, 286, 287, 287, 287, 287, 288, 288, 288, 326, 327, 327, 337, 337, 338, 338, 338, 338, 338, 338, 338, 338, 338, 339, 339, 339, 339, 339, 339, 339, 339, 339, 340, 340, 340, 340, 340, 340, 340, 341, 341, 341, 341, 341, 342, 342, 343, 343, 344, 382, 383, 383, 383, 383, 383, 383, 383, 383, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, 387, 387, 387, 387, 416, 416, 417, 418, 418, 419, 419, 420, 420, 420, 421, 423, 427, 428, 428, 429, 429, 430, 430, 431, 431, 432, 432, 433, 433, 434] 

В данных, где числа соединяются друг с другом, имеется около 8 точек. Основная проблема заключается в том, как найти эти места. Мы хотим создать массив для каждого пятна с числами в нем. Я думаю, что это простая проблема, но до сих пор не повезло узнать, как программировать это.

Я пробовал что-то с while и for loops, но ничего не получал. Какой был бы лучший способ сделать это?

+2

Что это за «8 пятен»? Каков ваш ожидаемый результат? – Kasramvd

+0

вывод должен быть в этом случае, 8 массивов с координатами пикселя из начального массива x и y –

+0

Я бы переделал его так, чтобы у вас было n x 2, то есть каждое местоположение xy, затем используйте расчет расстояния и np.with distance paddyg

ответ

1

Ну, я не уверен, почему это происходит с дополнительными местами, но они выглядят так, чтобы они соответствовали вашим спискам. Я получаю 175 пятен! (конечно, 2-4, 3-4, 3-5, 4-6, 5-6 выглядят в соответствии с вашими списками). Возможно, я использую другой критерий. Вот код для вас, чтобы взломать, как вы хотите:

import numpy as np 

a = np.array([[402, 401, 356, 355, 356, 355, 356, 386, 354, 355, 356, 386, 354, 355, 386, 354, 287, 288, 289, 290, 291, 292, 287, 288, 290, 291, 292, 293, 292, 293, 294, 295, 293, 294, 295, 296, 294, 295, 296, 146, 145, 146, 167, 168, 162, 163, 164, 165, 166, 167, 168, 169, 170, 160, 161, 162, 165, 166, 167, 168, 169, 170, 162, 163, 166, 167, 168, 169, 170, 163, 167, 168, 169, 170, 168, 169, 169, 170, 170, 310, 310, 311, 312, 313, 314, 315, 316, 317, 311, 312, 313, 314, 315, 316, 317, 311, 312, 313, 314, 315, 316, 311, 312, 313, 314, 315, 316, 311, 312, 313, 314, 274, 275, 275, 274, 275, 274, 275, 273, 274, 275, 274, 275, 274, 272, 273, 272, 273, 272, 273, 272, 273, 272, 273, 271, 272, 271], 
       [242, 243, 257, 258, 258, 259, 259, 259, 260, 260, 260, 260, 261, 261, 261, 262, 284, 284, 284, 284, 284, 284, 285, 285, 285, 285, 285, 285, 286, 286, 286, 286, 287, 287, 287, 287, 288, 288, 288, 326, 327, 327, 337, 337, 338, 338, 338, 338, 338, 338, 338, 338, 338, 339, 339, 339, 339, 339, 339, 339, 339, 339, 340, 340, 340, 340, 340, 340, 340, 341, 341, 341, 341, 341, 342, 342, 343, 343, 344, 382, 383, 383, 383, 383, 383, 383, 383, 383, 384, 384, 384, 384, 384, 384, 384, 385, 385, 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, 387, 387, 387, 387, 416, 416, 417, 418, 418, 419, 419, 420, 420, 420, 421, 423, 427, 428, 428, 429, 429, 430, 430, 431, 431, 432, 432, 433, 433, 434]]) 
a = a.T 
b = np.where(
     (abs(np.subtract.outer(a[:,0], a[:,0])) <= 1.0) & 
     (abs(np.subtract.outer(a[:,1], a[:,1])) <= 1.0)) 
non_dup = np.where(b[0] < b[1]) # remove double count and 'self' overlaps 
b = (b[0][non_dup], b[1][non_dup]) # remake slimmed down index 


def find_group(group, start): 
    st_ix = np.where(b[0] == start) 
    for i in st_ix[0]: 
    dest = b[1][i] 
    group.add(start) 
    group.add(dest) # is this needed? 
    find_group(group, dest) 

group_list = [] 

for i in b[0]: # NB this part is slow - it would be better to eliminate entries already dealt with - you can figure that out! 
    gp = set() 
    find_group(gp, i) 
    add_group = True 
    for old_gp in group_list: 
    if len(gp.intersection(old_gp)) > 0: # hopefully this has fixed it 
     old_gp = old_gp.union(gp) 
     add_group = False 
     break 
    if add_group: 
    group_list.append(gp) 


xy_list = [] 

for gp in group_list: 
    xy_list.append(np.array([a[i] for i in gp])) 

print(xy_list) 

EDIT модифицирована, как описано выше, чтобы создать список Numpy массивов смежных пикселей, как обсуждалось в комментариях. Результаты в этом

[array([[402, 242], 
    [401, 243]]), 
array([[356, 257], 
    [355, 258], 
    [356, 258], 
    [355, 259], 
    [356, 259], 
    [354, 260], 
    [355, 260], 
    [356, 260], 
    [354, 261], 
    [355, 261], 
    [354, 262]]), 
array([[386, 260], 
    [386, 261], 
    [386, 259]]), 
array([[287, 284], 
    [288, 284], 
    [289, 284], 
    [290, 284], 
    [291, 284], 
    [292, 284], 
    [287, 285], 
    [288, 285], 
    [290, 285], 
    [291, 285], 
    [292, 285], 
    [293, 285], 
    [292, 286], 
    [293, 286], 
    [294, 286], 
    [295, 286], 
    [293, 287], 
    [294, 287], 
    [295, 287], 
    [296, 287], 
    [294, 288], 
    [295, 288], 
    [296, 288]]), 
array([[145, 327], 
    [146, 327], 
    [146, 326]]), 
array([[167, 337], 
    [168, 337], 
    [166, 338], 
    [167, 338], 
    [168, 338], 
    [169, 338], 
    [170, 338], 
    [165, 339], 
    [166, 339], 
    [167, 339], 
    [168, 339], 
    [169, 339], 
    [170, 339], 
    [166, 340], 
    [167, 340], 
    [168, 340], 
    [169, 340], 
    [170, 340], 
    [167, 341], 
    [168, 341], 
    [169, 341], 
    [170, 341], 
    [168, 342], 
    [169, 342], 
    [169, 343], 
    [170, 343], 
    [170, 344]]), 
array([[163, 341], 
    [160, 339], 
    [161, 339], 
    [162, 339], 
    [162, 340], 
    [163, 340]]), 
array([[310, 382], 
    [310, 383], 
    [311, 383], 
    [312, 383], 
    [313, 383], 
    [314, 383], 
    [315, 383], 
    [316, 383], 
    [317, 383], 
    [311, 384], 
    [312, 384], 
    [313, 384], 
    [314, 384], 
    [315, 384], 
    [316, 384], 
    [317, 384], 
    [311, 385], 
    [312, 385], 
    [313, 385], 
    [314, 385], 
    [315, 385], 
    [316, 385], 
    [311, 386], 
    [312, 386], 
    [313, 386], 
    [314, 386], 
    [315, 386], 
    [316, 386], 
    [311, 387], 
    [312, 387], 
    [313, 387], 
    [314, 387]]), 
array([[274, 416], 
    [275, 416], 
    [275, 417], 
    [274, 418], 
    [275, 418], 
    [274, 419], 
    [275, 419], 
    [273, 420], 
    [274, 420], 
    [275, 420], 
    [274, 421]]), 
array([[272, 430], 
    [273, 430], 
    [272, 431], 
    [273, 431], 
    [272, 432], 
    [273, 432], 
    [271, 433], 
    [272, 433], 
    [271, 434], 
    [274, 427], 
    [273, 428], 
    [272, 429], 
    [273, 429]])] 
+0

Спасибо, но в массиве 137 баллов, и в этом массиве должно быть 8 точек с точками, поэтому я не думаю, что могу использовать ваш код. Я не понимаю ваш сценарий. –

+0

может дать немного больше объяснений того, что вы хотите. Мой код берет ваш первый массив как координату x, второй массив - как координату. Это правильно для начала? Затем он смотрит на расстояние между каждым из 137 пунктов и всеми остальными 137 точками (да расстояние от себя!) И сравнивает это с порогом (я использовал <= 1), тогда он отбрасывает дубликаты и самость. Очевидно, что существует более 137 межточечных расстояний. Мой расчет показывает, что есть 175, где расстояние == 1. Вы бы подсчитали точку 2 (356,257) -4 (356,258) в вашем 8ish? – paddyg

+0

Извините paddyg, координаты x и y - это точки для построения графика на 2-й сетке. его трудно объяснить, но форма сетки составляет 500 * 500, а комбинация массива (x) и массива (y) - это координата в сетке. Есть несколько групп с большим количеством координат, которые близки друг к другу (соседи по 1 пикселю), и я хочу сгруппировать их в новые массивы. –

1

Вот наивный способ сделать это:

from itertools import product 

def neighbours(xs,ys): 
    xys = list(zip(xs,ys)) 
    for x,y in product(range(max(xs)),range(max(ys))): 
    if (x,y) in xys: 
     if (x+1,y) in xys: 
     yield [(x,y),(x+1,y)] 
     if (x,y+1) in xys: 
     yield [(x,y),(x,y+1)] 

Для вашего входа, это создает что-то в виде [[(287, 287), (288, 287)], [(287, 287), (287, 288)], [(288, 288), (289, 288)], [(386, 386), (386, 387)], ...].

Чтобы получить список из 8 кортежей в качестве вывода, измените операторы yield [...] на отдельные операторы yield для каждого элемента списка.

+0

Спасибо, так как я использую данные, которые меняются каждый час, мы должны рассчитать количество кортежей и создать массив с содержащими в нем х и у! –

+0

@Marein, это то, что вы имели в виду под номерами, соединяющимися друг с другом? Код, кажется, смотрит на диагональ, так как x и y, очевидно, всегда будет одним и тем же значением из zip (range(), range()) – paddyg

+0

Право, мой код не имеет большого смысла. Исправлена. – Marein

Смежные вопросы