为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

达令说 2019-12-12 13:03:19
在有关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?感谢您的回答!
查看完整描述

2 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

也许此示例具有12个不同的数组值将有所帮助:


In [207]: x=np.arange(12).reshape(3,4).copy()


In [208]: x.flags

Out[208]: 

  C_CONTIGUOUS : True

  F_CONTIGUOUS : False

  OWNDATA : True

  ...

In [209]: x.T.flags

Out[209]: 

  C_CONTIGUOUS : False

  F_CONTIGUOUS : True

  OWNDATA : False

  ...

该C order值是,他们在生成的顺序。在调换哪些不是


In [212]: x.reshape(12,)   # same as x.ravel()

Out[212]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])


In [213]: x.T.reshape(12,)

Out[213]: array([ 0,  4,  8,  1,  5,  9,  2,  6, 10,  3,  7, 11])

您可以同时获得一维视图


In [214]: x1=x.T


In [217]: x.shape=(12,)

的形状x也可以更改。


In [220]: x1.shape=(12,)

---------------------------------------------------------------------------

AttributeError                            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.flags

Out[228]: 

  C_CONTIGUOUS : True

  F_CONTIGUOUS : False

  OWNDATA : True

  ...

In [229]: x2.shape=(12,)

看strides也许也有帮助。跨步是到达下一个值必须走多远(以字节为单位)。对于2d数组,将有2个跨步值:


In [233]: x=np.arange(12).reshape(3,4).copy()


In [234]: x.strides

Out[234]: (16, 4)

要到达下一行,请步进16个字节,仅下一列4。


In [235]: x1.strides

Out[235]: (4, 16)

转置只是切换跨步的顺序。下一行只有4个字节,即下一个数字。


In [236]: x.shape=(12,)


In [237]: x.strides

Out[237]: (4,)

改变形状也会改变步幅-一次仅通过缓冲区4个字节。


In [238]: x2=x1.copy()


In [239]: x2.strides

Out[239]: (12, 4)

即使x2看起来像x1,它也有自己的数据缓冲区,其值以不同的顺序排列。现在,下一列超过4个字节,而下一行为12(3 * 4)。


In [240]: x2.shape=(12,)


In [241]: x2.strides

Out[241]: (4,)

并且x,将形状更改为1d会将步幅减小为(4,)。


因为x1,按0,1,2,...顺序排列数据,不会产生一维的跨度0,4,8...。


__array_interface__ 是显示数组信息的另一种有用方法:


In [242]: x1.__array_interface__

Out[242]: 

{'strides': (4, 16),

 'typestr': '<i4',

 'shape': (4, 3),

 'version': 3,

 'data': (163336056, False),

 'descr': [('', '<i4')]}

该x1数据缓冲器地址将是相同x,同它的数据。 x2具有不同的缓冲区地址。


您也可以尝试order='F'在copy和reshape命令中添加参数。


查看完整回答
反对 回复 2019-12-12
  • 2 回答
  • 0 关注
  • 656 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信