我不完全确定如何标题这个问题。但是,如何获得一个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中做到这一点?
最后!我用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
到每个边缘。
这些填充距离定义在函数的顶部(tp
,bp
,...用于顶部垫,底部垫...),我们通过进行一些计算来确定。
计算基本上只是取其边缘和中心之间的距离并减去square_radius
。然而,如果我们把它留在这里,那么我们经常得到负填充距离(在半径小于到边缘的距离的情况下,所以为了解决这个问题,我们只需使用max()
函数和0
来进行填充)距离仅为正(需要填充)或0
(该边缘不需要填充)。
然后,通过所有这些定义,我们只需使用这些值调用pad
上的a
函数。
最后,我们使用您原来的“方形提取”技术来获得围绕中心坐标的方形。唯一的区别是我们需要通过顶部焊盘和左边焊盘来抵消所有索引。我们需要这样做,好像我们刚刚填充说左边的3个垫,然后原来是4的中心现在将是1的中心(因为索引从填充边缘开始)。因此,为了解决这个问题,我们只需通过在所有索引上添加填充差异来抵消索引。
希望你现在得到它!