科学计算基础软件包NumPy入门讲座(2):基本概念

举报
天元浪子 发表于 2022/05/08 00:50:44 2022/05/08
【摘要】 文章目录 1. 安装和导入2. NumPy数组的数据类型3. NumPy数组的属性4. 维、秩、轴5. 广播和矢量化 1. 安装和导入 NumPy的安装非常简单,直接使用 pip 命令安装...

1. 安装和导入

NumPy的安装非常简单,直接使用 pip 命令安装即可。强烈安装NumPy的时候一并安装SciPy模块和matplotlib模块,前者是包含图像处理、信号处理、空间计算、积分、聚类等专业性的科学计算工具包,后者是Python生态圈中应用最广泛的绘图库。

PS D:\>python –m pip install numpy scipy matplotlib

  
 
  • 1

使用NumPy时,通常习惯简写成 np。提醒大家注意:pip 命令需要在命令行窗口中运行,而不是在下图所示的IDEL窗口中。 在IDEL窗口中可以交互式执行Python语句,是学习 Python 的有力工具。

在这里插入图片描述

2. NumPy数组的数据类型

NumPy 支持的数据类型主要有整型(integrate)、浮点型(float)、布尔型(bool)和复数型(complex),每一种数据类型根据占用内存的字节数又分为多个不同的子类型。当然,NumPy 也支持自定义类型,我们在后面讲解数组排序的时候,再讨论自定义类型。
在这里插入图片描述
下面的例子演示了如何查看和指定数组的数据类型。

>>> a = np.array([0,1,2,3])
>>> a.dtype
dtype('int32')
>>> a = np.array([0,1,2,3.0])
>>> a.dtype
dtype('float64')
>>> a = np.array([0,1,2,3+0j])
>>> a.dtype
dtype('complex128')
>>> a = np.array([0,1,2,3], dtype=np.int16)
>>> a.dtype
dtype('int16')
>>> a = np.array([0,1,2,3], dtype=np.uint8)
>>> a.dtype
dtype('uint8')

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

dtype是数组的属性之一,可以很方便地查看数组的数据类型。创建数组时,如果不指定数据类型,NumPy会根据输入数据选择合适的数据类型。在较早期的版本中,指定数据类型的时候允许省略数据类型后面的数字,不过最新的版本已经限制这样的写法了。

3. NumPy数组的属性

刚才我们用dtype可以查看数组的数据类型,dtype是数组对象的属性之一,除了dtype,NumPy数组还有其他一些属性,详见下表。属性看起来有点多,但我们只需要记住dtypeshape两个属性就足可应对一般需求了。这两个属性非常重要,重要到你可以忽略其他的属性。

属性 说明
ndarray.dtype 元素类型
ndarray.shape 数组结构或形状
ndarray.size 数组元素个数
ndarray.itemsize 数组元素的大小,以字节为单位
ndarray.ndim 数组的维度数,也叫秩
ndarray.flags 数组的内存信息
ndarray.real 元素的实部
ndarray.imag 元素的虚部
ndarray.data 元素数组的实际存储区

下面是这些属性的演示操作:

>>> a = np.arange(24, dtype=np.complex64).reshape((2,3,4))
>>> a.dtype # 复数类型
dtype('complex64')
>>> a.shape # 2层3行4列
(2, 3, 4)
>>> a.size # 总共24个元素
24
>>> a.itemsize # 每个元素占用8个字节
8
>>> a.flags # 存储信息
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False
  UPDATEIFCOPY : False

>>> a.real # 实部
array([[[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.]],

       [[12., 13., 14., 15.],
        [16., 17., 18., 19.],
        [20., 21., 22., 23.]]], dtype=float32)
>>> a.imag # 虚部
array([[[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]],

       [[0., 0., 0., 0.],
        [0., 0., 0., 0.],
        [0., 0., 0., 0.]]], dtype=float32)
>>> a.data # 内存区域地址
<memory at 0x00000157D820BC78>
>>> a.ndim # 维度数(秩)
3

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

4. 维、秩、轴

维,就是维度。我们说数组是几维的,就是指维度,3维的数组,其维度数自然就是3。维度数,有一个专用名字,叫做秩,也就是上一节提到的数组属性 ndim。秩这个名字感觉有些多余,不如维度数更容易理解。但是,轴(axis)的概念一定要建立起来,并且要理解,因为轴的概念很重要。简单来说,可以把数组的轴,和笛卡尔坐标系的轴对应一下。

一维数组,类比于一维空间,只有一个轴,那就是0轴。
在这里插入图片描述

二维数组,类比于二维平面,有两个轴,我们习惯表示成行、列,那么行的方向就是0轴,列的方向就是1轴。
在这里插入图片描述
三维数组,类比于三维空间,有三个轴,我们习惯表示成层、行、列,那么层的方向就是0轴,行的方向就是1轴,列的方向就是2轴。
在这里插入图片描述

我们用一个求和的例子来演示一下轴概念的重要性。以三维数组为例,求和的需求会比较复杂,比如,分层求和,逐行求和,逐列求和等。这时候,轴(axis)就可以大显身手了。

>>> a = np.arange(18).reshape((3,2,3)) # 3层2行3列的结构
>>> a
array([[[ 0,  1,  2],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]],

       [[12, 13, 14],
        [15, 16, 17]]])
>>> np.sum(a) # 全部元素求和
153 
>>> np.sum(a, axis=0) # 层(0轴)方向求和,即所有层的对应元素求和
array([[18, 21, 24],
       [27, 30, 33]])
>>> np.sum(a, axis=1) # 行(1轴)方向求和,即各层列求和
array([[ 3,  5,  7],
       [15, 17, 19],
       [27, 29, 31]])
>>> np.sum(a, axis=2) # 列(2轴)方向求和,即各层行求和
array([[ 3, 12],
       [21, 30],
       [39, 48]])
>>> np.sum(np.sum(a, axis=1), axis=1) # 分层求和方法1
array([15, 51, 87])
>>> np.sum(np.sum(a, axis=2), axis=1) # 分层求和方法2
array([15, 51, 87])

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

只要理解了上面的操作,轴的概念就真正建立起来了。

5. 广播和矢量化

在讲两个概念之前,我们先思考两个问题:

  1. 整型数组各元素加1;
  2. 求两个等长整型数组对应元素之和组成的新数组。

若用python的列表实现的话,代码大约会这样写吧。

>>> x = list(range(5))
>>> for i in range(len(x)): # 遍历数组为每个元素加1
        x[i] += 1
>>> y = list(range(5,10))
>>> z = list()
>>> for i, j in zip(x, y): # 遍历两个数组,逐个元素求和
        z.append(i+j)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

用NumPy数组实现的话,代码就简洁多了,无需循环。

>>> a = np.arange(5)
>>> a += 1
>>> b = np.arange(5,10)
>>> c = a + b

  
 
  • 1
  • 2
  • 3
  • 4

显然,用NumPy数组实现起来,要比Python列表更简洁、更清晰。这得益于于NumPy的两大特性:广播矢量化

广播(broadcast)和矢量化(vectorization),是NumPy最精髓的特性,是NumPy的灵魂。所谓广播,就是将对数组的操作映射到每个数组元素上;矢量化可以理解为代码中没有显式的循环、索引等。NumPy数组最重要的特性是广播和矢量化,体现在性能上,就是接近C语言的运行效率,体现在代码上,则有这样的特点:

  1. 矢量化代码更简洁,更易于阅读
  2. 代码行越少意味着出错的几率越小
  3. 代码更接近于标准的数学符号
  4. 矢量化代码更pythonic

在这里插入图片描述

文章来源: xufive.blog.csdn.net,作者:天元浪子,版权归原作者所有,如需转载,请联系作者。

原文链接:xufive.blog.csdn.net/article/details/124593409

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。