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

时间:2017-12-24 19:19:36

标签: python numpy indexing

我不完全确定如何标题这个问题。但是,如何才能得到一个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中做到这一点?

1 个答案:

答案 0 :(得分: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,...用于顶部垫,底部垫...),我们通过进行一些计算来确定。< / p>

计算基本上只是取其边缘和中心之间的距离并减去square_radius。但是,如果我们将其留在此处,那么我们通常会得到负填充距离(在半径小于到边缘的距离的情况下,为了解决这个问题,我们只需使用max()函数和{ {1}}使填充距离仅为正(填充是必需的)或0(在该边缘不需要填充)。

然后,定义了所有这些内容后,我们只需使用这些值调用0上的pad函数。

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

希望你现在能得到它!