[英]Find all points within distance 1 of specific point in 2D numpy matrix
我想找到一個在我的numpy矩陣中一個點的范圍1(或完全對角線)范圍內的點列表 :
比如說我的矩陣m
是:
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 1 0 0]
[0 0 0 0 0]
[0 0 0 0 0]]
我想獲得一個元組列表或代表9點的所有坐標的元素,下面是X:
[[0 0 0 0 0]
[0 X X X 0]
[0 X X X 0]
[0 X X X 0]
[0 0 0 0 0]]
以下是邊緣上目標點的另一個示例:
[[0 0 0 0 0]
[0 0 0 0 0]
[0 0 0 0 1]
[0 0 0 0 0]
[0 0 0 0 0]]
在這種情況下,目標點的距離1內只有6個點:
[[0 0 0 0 0]
[0 0 0 X X]
[0 0 0 X X]
[0 0 0 X X]
[0 0 0 0 0]]
編輯:
使用David Herrings在這里回答/評論chebyshev距離是我嘗試解決上面的例子2,假設我知道目標點的坐標:
from scipy.spatial import distance
point = [2, 4]
valid_points = []
for x in range(5):
for y in range(5):
if(distance.chebyshev(point, [x,y]) <= 1):
valid_points.append([x,y])
print(valid_points) # [[1, 3], [1, 4], [2, 3], [2, 4], [3, 3], [3, 4]]
對於更大的陣列來說,這似乎有點低效,因為我只需要檢查一小部分單元格,而不是整個martix。
這里沒有感興趣的算法。 如果您還不知道 1的位置,首先您必須找到它,並且您不能比搜索每個元素做得更好。 ( 可以由具有得到一個恆定因數加速numpy
用做本中C速度argmax
;使用divmod
。在扁平的索引行和列分開)之后,你做的是添加±1(或0)的坐標,除非它將帶你超出數組范圍。 你永遠不會構造坐標只是為了以后丟棄它們。
我認為你讓它變得有點復雜 - 不需要依賴復雜的功能
import numpy as np
# set up matrix
x = np.zeros((5,5))
# add a single point
x[2,-1] = 1
# get coordinates of point as array
r, c = np.where(x)
# convert to python scalars
r = r[0]
c = c[0]
# get boundaries of array
m, n = x.shape
coords = []
# loop over possible locations
for i in [-1, 0, 1]:
for j in [-1, 0, 1]:
# check if location is within boundary
if 0 <= r + i < m and 0 <= c + j < n:
coords.append((r + i, c + j))
print(coords)
>>> [(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]
一種簡單的方法是使用笛卡爾積來獲得所有可能的坐標
設置數據:
x = np.array([[0,0,0], [0,1,0], [0,0,0]])
x
array([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])
您知道坐標將是您所在位置的+/- 1:
loc = np.argwhere(x == 1)[0] # unless already known or pre-specified
v = [loc[0], loc[0]-1, loc[0]+1]
h = [loc[1], loc[1]-1, loc[1]+1]
output = []
for i in itertools.product(v, h):
if not np.any(np.array(i) >= x.shape[0]) and not np.any(np.array(i) < 0): output.append(i)
print(output)
[(1, 1), (1, 0), (1, 2), (0, 1), (0, 0), (0, 2), (2, 1), (2, 0), (2, 2)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.