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