如何制作重复的"numpy"数组视图



如何将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.repeatnumpy.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]])

最新更新