假设我有一个数组:
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
我想通过定义矩阵的大小(而不是行/列索引)来获得始终位于x
中间的较小数组的副本
例如如果我想要一个2x2数组,它将返回:
[[5 6]
[9 10]]
出于我的目的,我的初始数组较大(4096x4096),我想复制中间正方形数组的副本,大小为(128x128),(256x256),(512x512),(1024x1024)和(2048x2048)。 / p>
我也想保留原始数组,所以我不必只从原始切片中切掉行/列,而是只希望修剪原始副本并保存到新变量中。
我正在考虑定义一些变量,例如(对于2x2情况):
rows_to_keep = [1,2]
cols_to_keep = [1,2]
然后使用
x[np.ix_(rows_to_keep, columns_to_keep)]
但是,当我的rows_to_keep
是最多2048个数字(例如,从4096x4096原始图像中复制128x128正方形我可以创建一个索引列表,该索引从1984年的row / col转到2112:
size_to_keep = 128
indices = np.linspace(0, size_to_keep, size_to_keep, endpoint=False)
rows_to_keep = [(4096/2)-(size_to_keep/2) + i for i in indices]
cols_to_keep = [(4096/2)-(size_to_keep/2) + i for i in indices]
copy_array = x[np.ix_(rows_to_keep, columns_to_keep)]
但是,这又变得混乱/不切实际。我希望有一种更Python化的方式来做到这一点?预先感谢
答案 0 :(得分:3)
由于所有索引都是连续的,因此您只需使用适当的slice
即可。显然,您无法避免计算极值,仅此而已。
这可以采取以下形式(包括一些代码以确保它适用于size
的任何整数值):
def get_center(arr, size):
mask = tuple(
slice(int(dim / 2 - size / 2), int(dim / 2 + size / 2))
if 0 < size < dim else slice(None)
for dim in arr.shape)
return arr[mask].copy()
可以简单地像这样使用:
import numpy as np
dim = 4
x = np.arange(dim * dim).reshape((dim, dim))
y = get_center(x, 2)
# [[ 5, 6],
# [ 9, 10]]
并按预期工作,但不占用太多内存。
当然,您可能希望调整自己的极值,以按自己喜欢的方式处理奇怪的情况(问题中并未真正定义)。
答案 1 :(得分:2)
Numpy可用于视图,这意味着您进行操作
extracted_middle_square = x[1:2,1:2]
您将看到x的视图(不是副本,并且x未被修改)。如果您要创建一个新变量,请
extracted_middle_square = x[1:2,1:2].copy()
这应该可以解决您的问题。