2、Numpy Ndarray 对象

1、番外说明

大家好,我是小P,本系列是本人对Python模块Numpy的一些学习记录,总结于此一方面方便其它初学者学习,另一方面害怕自己遗忘,希望大家喜欢。此外,对“目标检测/模型压缩/语义分割”感兴趣的小伙伴,欢迎加入QQ群 813221712 讨论交流,进群请看群公告!(可以点击如下连接直接加入!)
点击链接加入群聊【Object Detection】:https://jq.qq.com/?_wv=1027&k=5kXCXF8

2、正题

参考链接:

http://www.runoob.com/numpy/numpy-ndarray-object.html
https://cloud.tencent.com/developer/article/1106669

2.1 ndarray介绍

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。ndarray 对象是用于存放同类型元素的多维数组。ndarray 中的每个元素在内存中都有相同存储大小的区域。

NumPy的ndarray提供了一种将同质数据块(可以是连续或跨越)解释为多维数组对象的方式。正如你之前所看到的那样,数据类型(dtype)决定了数据的解释方式,比如浮点数、整数、布尔值等。

ndarray如此强大的部分原因是所有数组对象都是数据块的一个跨度视图(strided view)。你可能想知道数组视图arr[::2,::-1]不复制任何数据的原因是什么。简单地说,ndarray不只是一块内存和一个dtype,它还有跨度信息,这使得数组能以各种步幅(step size)在内存中移动。

ndarray 内部由以下内容组成:

● 一个指向数据(内存或内存映射文件中的一块数据)的指针,这个指针能够找到存储的数组值。

● 数据类型或 dtype,描述在数组中的固定大小值的格子。numpy有一套自己的类型,如np.int8、np.float32

● 一个表示数组形状(shape)的元组,表示各维度大小的元组。如(3,2)表示3行2列的数组

● 一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。

ndarray 的内部结构:
在这里插入图片描述
一个典型的(C顺序,稍后将详细讲解)3×4×5的float64(8个字节)数组,其跨度为(160,40,8),这儿跨度的计算根据数据的存储计算,数据三个维度,一共三个跨度。第一个跨度为4×5×8大小,跨一个二维矩阵平面,第二个跨度为5×8,跨一个矩阵的一行,第三个跨度为1×8,跨矩阵的一个元素

知道跨度是非常有用的,通常,跨度在一个轴上越大,沿这个轴进行计算的开销就越大。虽然NumPy用户很少会对数组的跨度信息感兴趣,但它们却是构建非复制式数组视图的重要因素。

可以通过如下代码获取数组的跨度,由此可见知道跨度的意义:

A=np.ones((3,4,5),dtype=np.float64)

A.shape
Out[13]: (3, 4, 5)

A
Out[14]: 
array([[[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]]])

A.strides
Out[15]: (160, 40, 8)

由上述可知,由第一维跨度160除以第二维跨度,可以知道矩阵的行数,同理,第二维除以第三维跨度可以知道矩阵的列数,这对于C语言中数据按行存储是非常关键的信息。

NumPy数据类型体系

你可能偶尔需要检查数组中所包含的是否是整数、浮点数、字符串或Python对象。因为浮点数的种类很多(从float16到float128),判断dtype是否属于某个大类的工作非常繁琐。幸运的是,dtype都有一个超类(比如np.integer和np.floating),它们可以跟np.issubdtype函数结合使用:

In [12]: ints = np.ones(10, dtype=np.uint16)

In [13]: floats = np.ones(10, dtype=np.float32)

In [14]: np.issubdtype(ints.dtype, np.integer)
Out[14]: True

In [15]: np.issubdtype(floats.dtype, np.floating)
Out[15]: True

其中,issubdtype函数用来判断某类是否是另一个类的子类

调用dtype的mro方法即可查看其所有的父类:

In [16]: np.float64.mro()
Out[16]:
[numpy.float64,
 numpy.floating,
 numpy.inexact,
 numpy.number,
 numpy.generic,
 float,
 object]

然后得到:

In [17]: np.issubdtype(ints.dtype, np.number)
Out[17]: True

其中,mro()用于获取某个类型的继承链,详细查询参考:https://study.163.com/course/courseLearn.htm?courseId=1005985001#/learn/video?lessonId=1053350157&courseId=1005985001

大部分NumPy用户完全不需要了解这些知识,但是这些知识偶尔还是能派上用场的。下图说明了dtype体系以及父子类关系。
在这里插入图片描述

2.2 ndarray创建数组

创建一个 ndarray 只需调用 NumPy 的 array 函数即可:

numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

参数说明:
在这里插入图片描述
实例
接下来可以通过以下实例帮助我们更好的理解。

实例 1
生成一个一维的数组

import numpy as np 
a = np.array([1,2,3])  
print (a)

输出结果如下:

array( [1, 2, 3])

实例 2
生成一个二维数组

import numpy as np 
a = np.array([[1,  2],  [3,  4]])  
print (a)

输出结果如下:

array([[1, 2],
       [3, 4]])

实例 3
通过ndmin参数指定生成数组的最小维度

import numpy as np 
a = np.array([1, 2, 3, 4, 5], ndmin =  2)  
print (a)

输出如下:

array([[1, 2, 3, 4, 5]])

注意,当指定ndmin=2时,则表示生成的数组维度为2,即a的维度为(1,5),默认前向扩展一维
实例 4
使用dtype 参数更改数据类型

import numpy as np 
a = np.array([1,  2,  3], dtype = complex)  
print (a)

输出结果如下:

array([1.+0.j, 2.+0.j, 3.+0.j])

这儿的数据类型为复数类型

ndarray 对象由计算机内存的连续一维部分组成,并结合索引模式,将每个元素映射到内存块中的一个位置。内存块以行顺序(C样式)或列顺序(FORTRAN或MatLab风格,即前述的F样式)来保存元素。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章