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

问题描述

如何numpy切片超出其形状,以便重复数组中的值而不必将整个数组存储在内存中?这就是我想要做的:

x = numpy.array([[1,2],[3,4]])
x[0:3,0:3]
->
[[1,2,1,4,3,4],[1,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),strides=(0,16,8))
In [21]: X
Out[21]: 
array([[[[1,[1,2]],[[3,4],4]]],[[[1,4]]]])

可以将其重塑为所需的数组:

In [22]: X.reshape(4,4)
Out[22]: 
array([[1,1,4,3,4]])

但是,重塑将创建X的副本。

(2,2)数组可以在计算中用作(1,2)数组,如果需要,可以将其扩展为(2,2):

In [25]: x[None,None,:,:]
Out[25]: 
array([[[[1,4]]]])
In [26]: np.broadcast_to(x,(2,2))
Out[26]: 
array([[[[1,4]],[[1,4]]]])

通过广播,我们可以在更大的计算中使用数组的视图。

,

NumPy数组不支持。数组在每个维度上都必须具有一致的步幅,而您想要的数组就不会那样。

您可以为结果实现自己的自定义类型,但它不能以NumPy的速度运行,并且不能与NumPy直接兼容-充其量,您尝试调用的任何NumPy函数都必须构建一个首先从您的对象中取出真实数组。

如果您的用例仅需要较小的切片,例如您的x[1238123:1238143,5328932:5328941]示例,则最好的选择是将切片端点调整为等效的较小值,然后平铺和切片。