像往常一样介绍,我是 python 初学者。但是,我有一个很大的项目要编码。它是一个带有元胞自动机的表面流模型。不管怎样,我还想在我的模型中包括建筑屋顶。假设您有一个 ascii 文件,用 1 表示建筑物,而其余的为 0。只有这两种状态。现在,我想找到所有指示同一建筑物的相邻单元格,并将它们(或者更确切地说是 y、x 和另一个(可能是高程)的信息,所以 3 列)存储在一个单独的建筑物数组中。请记住,建筑物可以有所有可能的形式,但对角连接的单元格不属于同一建筑物。因此只有北部、南部、西部和东部单元格可以属于同一建筑物。
我做了功课并用谷歌搜索,但到目前为止我找不到满意的答案。
例子: 初始土地覆盖阵列:
([0,0,0,0,0,0,0]
[0,0,1,0,0,0,0]
[0,1,1,1,0,1,1]
[0,1,0,1,0,0,1]
[0,0,0,0,0,0,0])
输出(我现在需要初始数组中单元格的坐标):
building_1=([1,2],[2,1],[2,2],[2,3],[3,1],[3,3])
building_2=([2,5],[2,6],[3,6])
非常感谢任何帮助!
最佳答案
您可以使用 label
来自 scipy.ndimage
的函数来识别不同的建筑物。
这是您的示例数组,包含两座建筑物:
In [57]: a
Out[57]:
array([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 1, 1],
[0, 1, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0]])
导入标签
。
In [58]: from scipy.ndimage import label
将 label
应用于 a
。它返回两个值:标记位置的数组,以及找到的不同对象(在本例中为建筑物)的数量。
In [59]: lbl, nlbls = label(a)
In [60]: lbl
Out[60]:
array([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 2, 2],
[0, 1, 0, 1, 0, 0, 2],
[0, 0, 0, 0, 0, 0, 0]], dtype=int32)
In [61]: nlbls
Out[61]: 2
要获取建筑物的坐标,可以使用 np.where
。例如,
In [64]: np.where(lbl == 2)
Out[64]: (array([2, 2, 3]), array([5, 6, 6]))
它返回一个数组元组;第 k
数组保存第 k
维度的坐标。例如,您可以使用 np.column_stack
将它们组合成一个数组:
In [65]: np.column_stack(np.where(lbl == 2))
Out[65]:
array([[2, 5],
[2, 6],
[3, 6]])
您可能需要所有坐标数组的列表。这是创建此类列表的一种方法。
为了方便起见,首先创建一个标签列表:
In [66]: labels = range(1, nlbls+1)
In [67]: labels
Out[67]: [1, 2]
使用列表理解来创建坐标数组列表。
In [68]: coords = [np.column_stack(where(lbl == k)) for k in labels]
In [69]: coords
Out[69]:
[array([[1, 2],
[2, 1],
[2, 2],
[2, 3],
[3, 1],
[3, 3]]),
array([[2, 5],
[2, 6],
[3, 6]])]
现在您的建筑数据位于labels
和coords
中。例如,第一个建筑物被标记为 labels[0]
,其坐标在 coords[0]
中:
In [70]: labels[0]
Out[70]: 1
In [71]: coords[0]
Out[71]:
array([[1, 2],
[2, 1],
[2, 2],
[2, 3],
[3, 1],
[3, 3]])
关于python - 如何在单独的numpy数组中对具有相同值的numpy数组元素进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22856169/