如何将numpy
数组切片到其形状之外,以便重复数组中的值,而不必将整个数组存储在内存中?以下是我想做的:
x = numpy.array([[1, 2], [3, 4]])
x[0:3, 0:3]
->
[[1, 2, 1, 2],
[3, 4, 3, 4],
[1, 2, 1, 2],
[3, 4, 3, 4]]
我知道numpy.repeat
和numpy.tile
,但它们都是阵列的副本,我希望像x[1238123:1238143,5328932:5328941]
一样对阵列进行切片,而不需要对较小的阵列进行数百万份拷贝。
使用strides
技巧,我们可以制作4d视图:
In [18]: x = numpy.array([[1, 2], [3, 4]])
In [19]: as_strided = np.lib.stride_tricks.as_strided
In [20]: X = as_strided(x, shape=(2,2,2,2), strides=(0,16,0,8))
In [21]: X
Out[21]:
array([[[[1, 2],
[1, 2]],
[[3, 4],
[3, 4]]],
[[[1, 2],
[1, 2]],
[[3, 4],
[3, 4]]]])
可以重塑为您想要的阵列:
In [22]: X.reshape(4,4)
Out[22]:
array([[1, 2, 1, 2],
[3, 4, 3, 4],
[1, 2, 1, 2],
[3, 4, 3, 4]])
但这种重塑将创建X
的副本。
该(2,2(数组可在计算中用作(1,1,2,2(数组,如果需要,可扩展为(2,2,2,2(:
In [25]: x[None,None,:,:]
Out[25]:
array([[[[1, 2],
[3, 4]]]])
In [26]: np.broadcast_to(x,(2,2,2,2))
Out[26]:
array([[[[1, 2],
[3, 4]],
[[1, 2],
[3, 4]]],
[[[1, 2],
[3, 4]],
[[1, 2],
[3, 4]]]])
因此,广播可以让我们在更大的计算中使用数组的视图。
NumPy数组不支持这一点。一个数组在每个维度上都必须有一个一致的步幅,而你想要的数组不会有这个步幅。
你可以为结果实现自己的自定义类型,但它不能以NumPy的速度工作,也不能直接与NumPy兼容——充其量,你试图调用的任何NumPy函数都必须首先从对象中构建一个真正的数组。
如果您的用例只需要小切片,如x[1238123:1238143,5328932:5328941]
示例,那么您最好的选择可能是将切片端点向下调整为等效的较小值,然后平铺并切片。
对于2D阵列使用numpy.ndarray.take
两次(对于3D阵列等使用三次(。每次都指定不同的轴。对于您需要的情况:
x.take(range(0, 4), mode='wrap', axis = 0).take(range(0, 4), mode='wrap', axis = 1)
这将产生
array([[1, 2, 1, 2],
[3, 4, 3, 4],
[1, 2, 1, 2],
[3, 4, 3, 4]])