CodeRoadMap
路线图学习路径文章题库资源社区

浏览

首页路线图学习路径知识库题库文章资源社区我的学习
CodeRoadMap

中文编程学习导航:路线图、讲义与题库,进度可同步。

路线图学习路径文章题库社区

© 2026 CodeRoadMap

津ICP备2026012044号-1|coderoadmap@126.com
首页/Python 100 天/70.NumPy的应用-3

课程目录

  1. 0101.初识Python
  2. 0202.第一个Python程序
  3. 0303.Python语言中的变量
  4. 0404.Python语言中的运算符
  5. 0505.分支结构
  6. 0606.循环结构
  7. 0707.分支和循环结构实战
  8. 0808.常用数据结构之列表-1
  9. 0909.常用数据结构之列表-2
  10. 1010.常用数据结构之元组
  11. 1111.常用数据结构之字符串
  12. 1212.常用数据结构之集合
  13. 1313.常用数据结构之字典
  14. 1414.函数和模块
  15. 1515.函数应用实战
  16. 1616.函数使用进阶
  17. 1717.函数高级应用
  18. 1818.面向对象编程入门
  19. 1919.面向对象编程进阶
  20. 2020.面向对象编程应用
  21. 2121.文件读写和异常处理
  22. 2222.对象的序列化和反序列化
  23. 2323.Python读写CSV文件
  24. 2424.Python读写Excel文件-1
  25. 2525.Python读写Excel文件-2
  26. 2626.Python操作Word和PowerPoint文件
  27. 2727.Python操作PDF文件
  28. 2828.Python处理图像
  29. 2929.Python发送邮件和短信
  30. 3030.正则表达式的应用
  31. 3131.Python语言进阶
  32. 3232-33.Web前端入门
  33. 3334-35.玩转Linux操作系统
  34. 3436.关系型数据库和MySQL概述
  35. 3537.SQL详解之DDL
  36. 3638.SQL详解之DML
  37. 3739.SQL详解之DQL
  38. 3840.SQL详解之DCL
  39. 3941.MySQL新特性
  40. 4042.视图、函数和过程
  41. 4143.索引
  42. 4244.Python接入MySQL数据库
  43. 4345.Hive实战
  44. 4446.Django快速上手
  45. 4547.深入模型
  46. 4648.静态资源和Ajax请求
  47. 4749.Cookie和Session
  48. 4850.制作报表
  49. 4951.日志和调试工具栏
  50. 5052.中间件的应用
  51. 5153.前后端分离开发入门
  52. 5254.RESTful架构和DRF入门
  53. 5355.RESTful架构和DRF进阶
  54. 5456.使用缓存
  55. 5557.接入三方平台
  56. 5658.异步任务和定时任务
  57. 5759.单元测试
  58. 5860.项目上线
  59. 5961.网络数据采集概述
  60. 6062.用Python获取网络资源-1
  61. 6162.用Python解析HTML页面-2
  62. 6263.并发编程在爬虫中的应用
  63. 6363.Python中的并发编程-1
  64. 6463.Python中的并发编程-2
  65. 6563.Python中的并发编程-3
  66. 6664.使用Selenium抓取网页动态内容
  67. 6765.爬虫框架Scrapy简介
  68. 6866.数据分析概述
  69. 6967.环境准备
  70. 7068.NumPy的应用-1
  71. 7169.NumPy的应用-2
  72. 7270.NumPy的应用-3
  73. 7371.NumPy的应用-4
  74. 7472.深入浅出pandas-1
  75. 7573.深入浅出pandas-2
  76. 7674.深入浅出pandas-3
  77. 7775.深入浅出pandas-4
  78. 7876.深入浅出pandas-5
  79. 7977.深入浅出pandas-6
  80. 8078.数据可视化-1
  81. 8179.数据可视化-2
  82. 8280.数据可视化-3
  83. 8381.浅谈机器学习
  84. 8482.k最近邻算法
  85. 8583.决策树和随机森林
  86. 8684.朴素贝叶斯算法
  87. 8785.回归模型
  88. 8886.K-Means聚类算法
  89. 8987.集成学习算法
  90. 9088.神经网络模型
  91. 9189.自然语言处理入门
  92. 9290.机器学习实战
  93. 9391.团队项目开发的问题和解决方案
  94. 9492.Docker容器技术详解
  95. 9593.MySQL性能优化
  96. 9694.网络API接口设计
  97. 9795.使用Django开发商业项目
  98. 9896.软件测试和自动化测试
  99. 9997.电商网站技术要点剖析
  100. 10098.项目部署上线和性能调优
  101. 10199.面试中的公共问题
  102. 102100.补充内容
第 72 课1 天

70.NumPy的应用-3

使用 NumPy 最为方便的是当需要对数组元素进行运算时,不用编写循环代码遍历每个元素,所有的运算都会自动的矢量化。简单的说就是,NumPy 中的数学运算和数学

课程内容

NumPy的应用-3

数组的运算

使用 NumPy 最为方便的是当需要对数组元素进行运算时,不用编写循环代码遍历每个元素,所有的运算都会自动的矢量化。简单的说就是,NumPy 中的数学运算和数学函数会自动作用于数组中的每个成员。

数组跟标量的运算

NumPy 的数组可以跟一个数值进行加、减、乘、除、求模、求幂等运算,对应的运算会作用到数组的每一个元素上,如下所示。

代码:

array1 = np.arange(1, 10)
print(array1 + 10)
print(array1 * 10)

输出:

[11 12 13 14 15 16 17 18 19]
[10 20 30 40 50 60 70 80 90]

除了上述的运算,关系运算也是没有问题的,之前讲布尔索引的时候已经遇到过了。

代码:

print(array1 > 5)
print(array1 % 2 == 0)

输出:

[False False False False False  True  True  True  True]
[False  True False  True False  True False  True False]

数组跟数组的运算

NumPy 的数组跟数组也可以执行算术运算和关系运算,运算会作用于两个数组对应的元素上,这就要求两个数组的形状(shape属性)要相同,如下所示。

代码:

array2 = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3])
print(array1 + array2)
print(array1 * array2)
print(array1 ** array2)

输出:

[ 2  3  4  6  7  8 10 11 12]
[ 1  2  3  8 10 12 21 24 27]
[  1   2   3  16  25  36 343 512 729]

代码:

print(array1 > array2)
print(array1 % array2 == 0)

输出:

[False  True  True  True  True  True  True  True  True]
[ True  True  True  True False  True False False  True]

通用一元函数

NumPy 中通用一元函数的参数是一个数组对象,函数会对数组进行元素级的处理,例如:函数会对数组中的每个元素计算平方根,而函数会对数组中的每个元素计算以2为底的对数,代码如下所示。

sqrt
log2

代码:

print(np.sqrt(array1))
print(np.log2(array1))

输出:

[1.         1.41421356 1.73205081 2.         2.23606798 2.44948974
 2.64575131 2.82842712 3.        ]
[0.         1.         1.5849625  2.         2.32192809 2.5849625
 2.80735492 3.         3.169925  ]

表1:通用一元函数

函数说明
abs / fabs求绝对值的函数
sqrt求平方根的函数,相当于array ** 0.5
square求平方的函数,相当于array ** 2
exp计算 $\small{e^x}$ 的函数,相当于np.e ** array
log / log10 / log2对数函数(e为底 / 10为底 / 2为底)
sign符号函数(1 - 正数;0 - 零;-1 - 负数)
ceil / floor上取整 / 下取整
isnan返回布尔数组,NaN对应True,非NaN对应False
isfinite / isinf判断数值是否为无穷大的函数
cos / cosh / sin三角函数
sinh / tan / tanh三角函数
arccos / arccosh / arcsin反三角函数
arcsinh / arctan / arctanh反三角函数
rint / round四舍五入函数

通用二元函数

NumPy 中通用二元函数的参数是两个数组对象,函数会对两个数组中的对应元素进行运算,例如:maximum函数会对两个数组中对应的元素找最大值,而power函数会对两个数组中对应的元素进行求幂操作,代码如下所示。

代码:

array3 = np.array([[4, 5, 6], [7, 8, 9]])
array4 = np.array([[1, 2, 3], [3, 2, 1]])
print(np.maximum(array3, array4))
print(np.power(array3, array4))

输出:

[[4 5 6]
 [7 8 9]]
[[  4  25 216]
 [343  64   9]]

表2:通用二元函数

函数说明
add(x, y) / substract(x, y)加法函数 / 减法函数
multiply(x, y) / divide(x, y)乘法函数 / 除法函数
floor_divide(x, y) / mod(x, y)整除函数 / 求模函数
allclose(x, y)检查数组x和y元素是否几乎相等
power(x, y)数组x的元素 $\small{x_{i}}$ 和数组y的元素 $\small{y_{i}}$,计算 $\small{x_{i}^{y_{i}}}$
maximum(x, y) / fmax(x, y)两两比较元素获取最大值 / 获取最大值(忽略NaN)
minimum(x, y) / fmin(x, y)两两比较元素获取最小值 / 获取最小值(忽略NaN)
dot(x, y)点积运算(数量积,通常记为 $\small{\cdot}$ ,用于欧几里得空间(Euclidean space))
inner(x, y)内积运算(内积的含义要高于点积,点积相当于是内积在欧几里得空间 $\small{\mathbb{R}^{n}}$ 的特例,而内积可以推广到赋范向量空间,只要它满足平行四边形法则即可)
cross(x, y) 叉积运算(向量积,通常记为 $\small{\times}$ ,运算结果是一个向量)
outer(x, y)外积运算(张量积,通常记为 $\small{\bigotimes}$ ,运算结果通常是一个矩阵)
intersect1d(x, y)计算x和y的交集,返回这些元素构成的有序数组
union1d(x, y)计算x和y的并集,返回这些元素构成的有序数组
in1d(x, y)返回由判断x 的元素是否在y中得到的布尔值构成的数组
setdiff1d(x, y)计算x和y的差集,返回这些元素构成的数组
setxor1d(x, y)计算x和y的对称差,返回这些元素构成的数组

说明:关于向量和矩阵的运算,我们在下一个章节加以说明。

广播机制

上面数组运算的例子中,两个数组的形状(shape属性)是完全相同的,我们再来研究一下,两个形状不同的数组是否可以直接做二元运算或使用通用二元函数进行运算,请看下面的例子。

代码:

array5 = np.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
array6 = np.array([1, 2, 3])
array5 + array6

输出:

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

代码:

array7 = np.array([[1], [2], [3], [4]])
array5 + array7

输出:

array([[1, 1, 1],
       [3, 3, 3],
       [5, 5, 5],
       [7, 7, 7]])

通过上面的例子,我们发现形状不同的数组仍然有机会进行二元运算,但这不代表任意形状的数组都可以进行二元运算。简单的说,只有两个数组后缘维度相同或者后缘维度不同但其中一个数组后缘维度为1时,广播机制才会被触发。通过广播机制,NumPy 将两个原本形状不相同的数组变成形状相同,才能进行二元运算。所谓后缘维度,指的是数组形状(shape属性)从后往前看对应的部分,我们举例说明。

上图中,一个数组的形状是(4, 3),另一个数组的形状是(3, ),从后往前看对应的部分都是3,属于后缘维度相同,可以应用广播机制,第二个数组会沿着缺失元素那个轴的方向去广播自己,最终让两个数组形状达成一致。

上图中,一个数组的形状是(3, 4, 2),另一个数组的形状是(4, 2),从后往前看对应的部分都是(4, 2),属于后缘维度相同,可以应用广播机制,第二个数组会沿着缺失元素那个轴的方向去广播自己,最终让两个数组形状达成一致。

上图中,一个数组的形状是(4, 3),另一个数组的形状是(4, 1),这是后缘维度不相同的情况,但是第二个数组跟第一个数组不同的地方为1,第二个数组可以沿着为1 的那个轴广播自己,最终让两个数组形状达成一致。

思考:一个3行1列的二维数组和一个1行3列的二维数组能够执行加法运算吗?

其他常用函数

除了上面讲到的函数外,NumPy 中还提供了很多用于处理数组的函数,ndarray对象的很多方法也可以通过调用函数来实现,下表给出了一些常用的函数。

表3:NumPy其他常用函数

函数说明
unique去除数组重复元素,返回唯一元素构成的有序数组
copy返回拷贝数组得到的数组
sort返回数组元素排序后的拷贝
split / hsplit / vsplit将数组拆成若干个子数组
stack / hstack / vstack将多个数组堆叠成新数组
concatenate沿着指定的轴连接多个数组构成新数组
append / insert向数组末尾追加元素 / 在数组指定位置插入元素
argwhere找出数组中非0元素的位置
extract / select / where按照指定的条件从数组中抽取或处理数组元素
flip沿指定的轴翻转数组中的元素
fromregex通过读取文件和正则表达式解析获取数据创建数组对象
repeat / tile通过对元素的重复来创建新数组
roll沿指定轴对数组元素进行移位
resize重新调整数组的大小
place / put将数组中满足条件的元素/指定的元素替换为指定的值
partition用选定的元素对数组进行一次划分并返回划分后的数组

去重(重复元素只保留一项)。

代码:

np.unique(array5)

输出:

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

堆叠和拼接。

代码:

array8 = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])
array9 = np.array([[4, 4, 4], [5, 5, 5], [6, 6, 6]])
np.hstack((array8, array9))

输出:

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

代码:

np.vstack((array8, array9))

输出:

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

代码:

np.concatenate((array8, array9))

输出:

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

代码:

np.concatenate((array8, array9), axis=1)

输出:

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

追加和插入元素。

代码:

np.append(array1, [10, 100])

输出:

array([  1,   2,   3,   4,   5,   6,   7,   8,   9,  10, 100])

代码:

np.insert(array1, 1, [98, 99, 100])

输出:

array([  1,  98,  99, 100,   2,   3,   4,   5,   6,   7,   8,   9])

抽取和处理元素。

代码:

np.extract(array1 % 2 != 0, array1)

输出:

array([1, 3, 5, 7, 9])

说明:上面extract函数的操作相当于我们之前讲的布尔索引。

代码:

np.select([array1 <= 3, array1 >= 7], [array1 * 10, array1 ** 2])

输出:

array([10, 20, 30,  0,  0,  0, 49, 64, 81])

说明:上面select函数的第一个参数设置了两个条件,满足第一个条件的元素执行了乘以10的操作,满足第二个条件的元素执行了求平方的操作,两个条件都不能满足的数组元素会被处理为0。

代码:

np.where(array1 <= 5, array1 * 10, array1 ** 2)

输出:

array([10, 20, 30, 40, 50, 36, 49, 64, 81])

说明:上面where函数的第一个参数给出了条件,满足条件的元素执行了乘以10的操作,不能满足条件的元素执行了求平方的操作。

重复数组元素创建新数组。

代码:

np.repeat(array1, 3)

输出:

array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9])

代码:

np.tile(array1, 2)

输出:

array([1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9])

调整数组大小。

代码:

np.resize(array1, (5, 3))

输出:

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9],
       [1, 2, 3],
       [4, 5, 6]])

提示:array1原本是一个有9个元素的一维数组,通过resize函数调整成为5行3列共15个元素的二维数组,缺少的元素通过复用原数组中的元素来补充。

代码:

 np.resize(array5, (2, 4))

输出:

array([[0, 0, 0, 1],
       [1, 1, 2, 2]])

替换数组元素。

代码:

np.put(array1, [0, 1, -1, 3, 5], [100, 200])
array1

输出:

array([100, 200,   3, 200,   5, 100,   7,   8, 100])

说明:上面put函的第二个参数给出了要被替换的元素的索引,但是用来作为替换值的元素只有100和200,所以这两个值会被循环使用,因此索引为0、1、-1、3、5的元素被依次替换成了100、200、100、200、100。

代码:

np.place(array1, array1 > 5, [1, 2, 3])
array1

输出:

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

注意:put函数和place函数都没有返回新的数组对象,而是在原来的数组上直接进行替换。

← 上一课69.NumPy的应用-2下一课 →71.NumPy的应用-4