在数组中找到最“空”的位置

4
假设我有以下的numpy数组:
foo = np.asarray([
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
])

正如你所看到的,它包含一些0和1。我正在寻找这个数组中最“空”的位置。我的意思是:您可以找到更高密度的0的位置。我想编写一个函数,以返回该位置的行和列索引的中心。

目前,我尝试使用以下函数将该数组分为四个相同大小的部分:

def blockshaped(arr, nrows, ncols):
    """Return an array of shape (n, nrows, ncols)."""
    h, w = arr.shape
    arr = arr.reshape(h // nrows, nrows, -1, ncols)
    arr = arr.swapaxes(1, 2)
    arr = arr.reshape(-1, nrows, ncols)

    return (arr)

然后我计算每个部分的总和。找到总和最小的位置并再次将其分成4份,以此类推...但我感觉这不是正确的做法...


你是在寻找相邻元素和为0的最大区域,还是这个“地方”必须具有特定的形状?因为如果不需要特定形状,你可以返回任何一个值为0的元素,它将具有可能的最高密度。 - alexshchep
嗯,那个重复的问题基本上和你的问题一样,有一个被接受的答案,但是在“中心查找”部分有点含糊。 - roganjosh
可能是距离中心最近的点? - Olivier Melançon
@roganjosh 我正在检查这是否真的是我正在寻找的,但看起来很不错 :) - snoob dogg
我正在努力想出如何完成它。重复部分已经接近完成并且我已经标记了它,但是我对它的结尾不太满意,所以我正在努力找到完成步骤。 - roganjosh
显示剩余6条评论
1个回答

1
我基本上是从 Efficient way to find the largest area of a specific value in a 2D numpy array 借用代码,但它没有找到(或者至少没有定义)中心。为此,我们可以使用 ndimage.measurements.center_of_mass
import numpy as np
from scipy import ndimage

foo = np.asarray([
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
    [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
])

label, num_label = ndimage.label(foo == 0)
size = np.bincount(label.ravel())
biggest_label = size[1:].argmax() + 1
clump_mask = label == biggest_label

center = ndimage.measurements.center_of_mass(clump_mask)

这将会得到:(7.238095238095238, 6.571428571428571)

完美地满足了我的需求 :) - snoob dogg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接