在numpy数组中填入一个超出范围的部分

问题描述 投票:2回答:1

我不完全确定如何标题这个问题。但是,如何获得一个numpy数组的一部分,它将具有一些超出边界的值?

请参阅下面的简单示例代码:

def get_section(a, center, square_radius):
    return a[center[0] - square_radius:center[0] + square_radius + 1, \
              center[1] - square_radius:center[1] + square_radius + 1]



array = [
    [1, 2, 3, 4, 5, 6, 7, 8, 9],
    [2, 3, 4, 5, 6, 7, 8, 9, 1],
    [3, 4, 5, 0, 7, 8, 9, 1, 2],
    [4, 5, 6, 7, 8, 9, 1, 2, 3],
    [5, 0, 7, 8, 9, 4, 5, 6, 7],
    [6, 7, 8, 9, 1, 2, 3, 4, 5]
]
a = np.asarray(array)
square_radius = 2


center = [2,3]
print(get_section(a, center, square_radius))

center = [4,1]
print(get_section(a, center, square_radius))

假设我有一个数组,但我希望得到它的一小部分,通过指定我想要的部分的中心和半径。

第一个将打印出来:

[[2 3 4 5 6]
 [3 4 5 6 7]
 [4 5 0 7 8]
 [5 6 7 8 9]
 [0 7 8 9 4]]

这正是我想要的。为简单起见,我将“0”放在所识别的2个示例的中心。

但第二个将打印出[]

对于第二个,我想用-1填充外部值。因此,我希望它返回:

[[-1  3  4  5  0]
 [-1  4  5  6  7]
 [-1  5  0  7  8]
 [-1  6  7  8  9]
 [-1 -1 -1 -1 -1]]

我怎么能在numpy中做到这一点?

python numpy indexing
1个回答
1
投票

最后!我用np.pad完成了它。我不确定是否有更好的方法来做到这一点,因为它最终变得相当复杂,然而,它工作正常:

def get_section(a, center, square_radius):
    tp = max(0, -(center[0] - square_radius))
    bp = max(0, -((a.shape[0]-center[0]-1) - square_radius))
    lp = max(0, -(center[1] - square_radius))
    rp = max(0, -((a.shape[1]-center[1]-1) - square_radius))
    a = np.pad(a, [[tp, bp], [lp, rp]], 'constant', constant_values=-1)
    return a[center[0] - square_radius + tp:center[0] + square_radius + 1 + tp, \
              center[1] - square_radius + lp:center[1] + square_radius + 1 + lp]

并使用您的示例进行测试:

>>> center = [2,3]
>>> print(get_section(a, center, square_radius))
[[2 3 4 5 6]
 [3 4 5 6 7]
 [4 5 0 7 8]
 [5 6 7 8 9]
 [0 7 8 9 4]]
>>> center = [4,1]
>>> print(get_section(a, center, square_radius))
[[-1  3  4  5  0]
 [-1  4  5  6  7]
 [-1  5  0  7  8]
 [-1  6  7  8  9]
 [-1 -1 -1 -1 -1]]

为什么?

首先,让我们定义一个数组来测试np.pad()函数:

>>> a
array([[1, 2],
       [3, 4]])

然后我们可以快速演示填充的工作原理,从这个例子中它应该是相当不言自明的:

>>> np.pad(a, [[1, 2], [0, 3]], 'constant', constant_values=-1)
array([[-1, -1, -1, -1, -1],
       [ 1,  2, -1, -1, -1],
       [ 3,  4, -1, -1, -1],
       [-1, -1, -1, -1, -1],
       [-1, -1, -1, -1, -1]])

所以我们现在知道我们可以将-1s添加到我们想要的任何边缘,我们现在只需要解决(如第二个例子中的方形与边缘重叠),如果是这样,我们需要添加多少个-1s到每个边缘。

这些填充距离定义在函数的顶部(tpbp,...用于顶部垫,底部垫...),我们通过进行一些计算来确定。

计算基本上只是取其边缘和中心之间的距离并减去square_radius。然而,如果我们把它留在这里,那么我们经常得到负填充距离(在半径小于到边缘的距离的情况下,所以为了解决这个问题,我们只需使用max()函数和0来进行填充)距离仅为正(需要填充)或0(该边缘不需要填充)。

然后,通过所有这些定义,我们只需使用这些值调用pad上的a函数。

最后,我们使用您原来的“方形提取”技术来获得围绕中心坐标的方形。唯一的区别是我们需要通过顶部焊盘和左边焊盘来抵消所有索引。我们需要这样做,好像我们刚刚填充说左边的3个垫,然后原来是4的中心现在将是1的中心(因为索引从填充边缘开始)。因此,为了解决这个问题,我们只需通过在所有索引上添加填充差异来抵消索引。

希望你现在得到它!

© www.soinside.com 2019 - 2024. All rights reserved.