[英]How to find regions of ones surrounded by zeros in a numpy array?
我有一個 numpy 數組,比如
arr1 = np.array([1,1,1,1,0,0,1,1,1,0,0,0,1,1])
arr2 = np.array([1,1,1,1,0,0,0,1,1,1,1,1,1,1])
0
-water 1
-land 我想找到周圍有水的島嶼的索引。 例如,在arr1
中,水從索引4
開始,島嶼索引6
到8
被兩個水帶包圍。 所以arr1
的答案是
[4,5,6,7,8,9,10,11]
但在第二種情況下,沒有被水包圍的土地,所以沒有 output。
以下方法在數組的開頭和結尾填充一個。 並計算差異:從水到陸地時為-1
,從陸地到水時為1
,其他地方為0
。
下面的代碼構造了一系列的測試用例,將function可視化。 它可以作為對期望結果的不同定義的測試平台。
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
def find_islands(arr):
d = np.diff(np.pad(arr, pad_width=(1, 1), constant_values=1))
land_starts, = np.nonzero(d == 1)
land_ends, = np.nonzero(d == -1)
if len(land_starts) > 1 and len(land_ends) > 1:
return np.arange(arr.size)[land_ends[0]: land_starts[-1]]
else:
return None
def show_array(arr, y, color0='skyblue', color1='limegreen'):
if arr is not None:
plt.imshow(arr[np.newaxis, :], cmap=ListedColormap([color0, color1]), vmin=0, vmax=1,
extent=[0, arr.size, y, y + 2])
def mark_array(arr, y, color0='none', color1='crimson'):
if arr is not None:
pix = np.zeros(arr[-1] + 1)
pix[arr] = 1
show_array(pix, y, color0, color1)
tests = [np.array([1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1]),
np.array([1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]),
np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]),
np.array([0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1]),
np.array([1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
np.array([1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0]),
np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0]),
np.array([0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0]),
np.array([1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0])]
for arr, y in zip(tests, range(0, 1000, 5)):
show_array(arr, y + 2)
result = find_islands(arr)
mark_array(result, y)
ax = plt.gca()
ax.relim()
ax.autoscale()
ax.axis('auto')
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.