假设我有一个数组:
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) 的中间方形数组。
我还想保留原始数组,所以我不一定要从原始数组中切掉行/列,而是我想要原始数组的一个副本,只修剪,保存到一个新变量。
我正在考虑定义一些变量,例如(对于 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 的正方形,我可以创建一个索引列表,从 row/col 1984 开始到 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)]
但这再次变得困惑/不切实际。我希望有更多的 pythonic 方式来做到这一点?提前致谢
最佳答案
由于您所有的索引都是连续的,您可以简单地使用适当的 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]]
并按预期工作,但不会占用那么多内存。
当然,您可能希望调整您的极值以按照您喜欢的方式处理奇怪的情况(您的问题中并未真正定义)。
关于python - 在 Python 中从较大的方阵 (n,n) 复制较小的方阵 (m,m),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52369746/