猿问

连续数组和非连续数组有什么区别?

在有关reshape()函数的numpy手册中,它说


>>> a = np.zeros((10, 2))

# A transpose make the array non-contiguous

>>> b = a.T

# Taking a view makes it possible to modify the shape without modifying the

# initial object.

>>> c = b.view()

>>> c.shape = (20)

AttributeError: incompatible shape for a non-contiguous array

我的问题是:


什么是连续和不连续数组?它类似于C 中的连续内存块吗?什么是连续内存块?

两者之间在性能上有什么区别吗?我们什么时候应该使用其中一个?

为什么转置会使数组不连续?

为什么会c.shape = (20)引发错误incompatible shape for a non-contiguous array?

感谢您的回答!


达令说
浏览 657回答 2
2回答

慕勒3428872

也许此示例具有12个不同的数组值将有所帮助:In [207]: x=np.arange(12).reshape(3,4).copy()In [208]: x.flagsOut[208]:&nbsp;&nbsp; C_CONTIGUOUS : True&nbsp; F_CONTIGUOUS : False&nbsp; OWNDATA : True&nbsp; ...In [209]: x.T.flagsOut[209]:&nbsp;&nbsp; C_CONTIGUOUS : False&nbsp; F_CONTIGUOUS : True&nbsp; OWNDATA : False&nbsp; ...该C order值是,他们在生成的顺序。在调换哪些不是In [212]: x.reshape(12,)&nbsp; &nbsp;# same as x.ravel()Out[212]: array([ 0,&nbsp; 1,&nbsp; 2,&nbsp; 3,&nbsp; 4,&nbsp; 5,&nbsp; 6,&nbsp; 7,&nbsp; 8,&nbsp; 9, 10, 11])In [213]: x.T.reshape(12,)Out[213]: array([ 0,&nbsp; 4,&nbsp; 8,&nbsp; 1,&nbsp; 5,&nbsp; 9,&nbsp; 2,&nbsp; 6, 10,&nbsp; 3,&nbsp; 7, 11])您可以同时获得一维视图In [214]: x1=x.TIn [217]: x.shape=(12,)的形状x也可以更改。In [220]: x1.shape=(12,)---------------------------------------------------------------------------AttributeError&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Traceback (most recent call last)<ipython-input-220-cf2b1a308253> in <module>()----> 1 x1.shape=(12,)AttributeError: incompatible shape for a non-contiguous array但是移调的形状无法更改。在data仍处于0,1,2,3,4...顺序,这不能被访问访问如0,4,8...在一维数组。但是x1可以更改的副本:In [227]: x2=x1.copy()In [228]: x2.flagsOut[228]:&nbsp;&nbsp; C_CONTIGUOUS : True&nbsp; F_CONTIGUOUS : False&nbsp; OWNDATA : True&nbsp; ...In [229]: x2.shape=(12,)看strides也许也有帮助。跨步是到达下一个值必须走多远(以字节为单位)。对于2d数组,将有2个跨步值:In [233]: x=np.arange(12).reshape(3,4).copy()In [234]: x.stridesOut[234]: (16, 4)要到达下一行,请步进16个字节,仅下一列4。In [235]: x1.stridesOut[235]: (4, 16)转置只是切换跨步的顺序。下一行只有4个字节,即下一个数字。In [236]: x.shape=(12,)In [237]: x.stridesOut[237]: (4,)改变形状也会改变步幅-一次仅通过缓冲区4个字节。In [238]: x2=x1.copy()In [239]: x2.stridesOut[239]: (12, 4)即使x2看起来像x1,它也有自己的数据缓冲区,其值以不同的顺序排列。现在,下一列超过4个字节,而下一行为12(3 * 4)。In [240]: x2.shape=(12,)In [241]: x2.stridesOut[241]: (4,)并且x,将形状更改为1d会将步幅减小为(4,)。因为x1,按0,1,2,...顺序排列数据,不会产生一维的跨度0,4,8...。__array_interface__ 是显示数组信息的另一种有用方法:In [242]: x1.__array_interface__Out[242]:&nbsp;{'strides': (4, 16),&nbsp;'typestr': '<i4',&nbsp;'shape': (4, 3),&nbsp;'version': 3,&nbsp;'data': (163336056, False),&nbsp;'descr': [('', '<i4')]}该x1数据缓冲器地址将是相同x,同它的数据。 x2具有不同的缓冲区地址。您也可以尝试order='F'在copy和reshape命令中添加参数。
随时随地看视频慕课网APP

相关分类

Python
我要回答