在python中找到np数组中的邻居

时间:2015-05-01 13:36:12

标签: python arrays numpy

我有2个带有网格像素坐标的数组。

[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循环,但结果却什么都没有。最好的方法是什么?

2 个答案:

答案 0 :(得分: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语句。

答案 1 :(得分:1)

嗯,我不确定为什么它会提出额外的位置,但它们看起来在你的列表中匹配。我得到175个点! (当然2-4,4-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]])]