zoukankan      html  css  js  c++  java
  • numpy中array数组对象的储存方式(n,1)和(n,)的区别

      资料:https://stackoverflow.com/questions/22053050/difference-between-numpy-array-shape-r-1-and-r

      这篇文章是我偶然点开的stackoverflow上的一个问题,是关于numpy中的array对象的。numpy在python、机器学习界的重要地位不用多说了吧。在此把这个回答翻译领悟一下,以供学习。

      注:仅为学习目的翻译,作者是Gareth Rees,可能会有我自己的修改。

      For learning purposes only !!!

      看待NumPy arrays的最好方式是把它分为两个部分,一个数据缓冲区包含了一块raw elements(原始元素),以及一个view(我叫它视窗)来描述解释数据缓冲区。

      例如如果我们创建一个包含12个整型数的数组 a 

    >>> a = numpy.arange(12)
    >>> a
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    

      则 a 包含了一个数据缓冲区,储存成如下的样子:

    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      以及一个视窗,定义了怎样解释数据:

    >>> a.flags
      C_CONTIGUOUS : True
      F_CONTIGUOUS : True
      OWNDATA : True
      WRITEABLE : True
      ALIGNED : True
      UPDATEIFCOPY : False
    >>> a.dtype
    dtype('int64')
    >>> a.itemsize
    8
    >>> a.strides
    (8,)
    >>> a.shape
    (12,)
    

      在这里,shape=(12,)意味着这个数组仅仅被一个索引支配:从0到11。从概念上讲,假如我们使用这个单独的索引给 打上标签,那么 a 将看起来像这样:

    i= 0    1    2    3    4    5    6    7    8    9   10   11
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      reshape一个数组的操作不会改变数据缓冲区,而是创建一个新的解释数据的视窗。

    >>> b = a.reshape((3, 4))
    

      上面的操作创建了一个和 拥有同一个数据缓冲区的 ,但是现在它被两个索引所支配(two-dimensions indexed)。一个从0到2,一个从0到3,假如我们给数据打上标签,b 看起来会像这样:

    i= 0    0    0    0    1    1    1    1    2    2    2    2
    j= 0    1    2    3    0    1    2    3    0    1    2    3
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      这也意味着:

    >>> b[2,1]
    9
    

      第二个索引比第一个索引变化的快,假如想反过来,可以使用下面的参数创造一个数组 c 

    >>> c = a.reshape((3, 4), order='F')
    

      补充:order='F'或者order='C'表示数组的索引方式分别像C语言或者Fortran,'C'是缺省值

      这样会产生一个有如下索引的数组:

    i= 0    1    2    0    1    2    0    1    2    0    1    2
    j= 0    0    0    1    1    1    2    2    2    3    3    3
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      意味着

    >>> c[2,1]
    5
    

      有了前面的铺垫,就很容易理解下面一个例子了:

    >>> d = a.reshape((12, 1))
    

      数组被两个索引支配,第一个索引从0到11,第二个索引始终为0:

    i= 0    1    2    3    4    5    6    7    8    9   10   11
    j= 0    0    0    0    0    0    0    0    0    0    0    0
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      所以:

    >>> d[10,0]
    10
    

      一个展平的一维数组从某种意义上来说是自由的,所以我们完全可以自己定义每一维的大小:

    >>> e = a.reshape((1, 2, 1, 6, 1))
    

      上面的操作创建了一个这样的数组:

    i= 0    0    0    0    0    0    0    0    0    0    0    0
    j= 0    0    0    0    0    0    1    1    1    1    1    1
    k= 0    0    0    0    0    0    0    0    0    0    0    0
    l= 0    1    2    3    4    5    0    1    2    3    4    5
    m= 0    0    0    0    0    0    0    0    0    0    0    0
    ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐
    │  0 │  1 │  2 │  3 │  4 │  5 │  6 │  7 │  8 │  9 │ 10 │ 11 │
    └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘
    

      所以:

    >>> e[0,1,0,0,0]
    6
  • 相关阅读:
    大型网站架构
    Swift 2.x 升为 swift 3后语法不兼容问题适配
    Redis开发
    你必须知道的Dockerfile
    JAVA知识点汇总
    JAVA知识点汇总
    nginx location配置详细解释
    python3 urllib.request.Request的用法
    拉勾网python开发要求爬虫
    爬虫工程师是干什么的?你真的知道了吗?
  • 原文地址:https://www.cnblogs.com/chester-cs/p/12682612.html
Copyright © 2011-2022 走看看