开发者社区> 问答> 正文

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

在有关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? 感谢您的回答! 问题来源于stack overflow

展开
收起
保持可爱mmm 2020-02-08 19:23:26 563 0
1 条回答
写回答
取消 提交回答
  • 也许此示例具有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) in () ----> 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命令中添加参数。

    2020-02-08 19:23:42
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载