Numpy 简介
Numpy 库是机器学习四个基础库(Numpy、Matplotlib、Pandas、Sklearn)之一,机器学习算法中大部分都是调用 Numpy 库来完成基础数值计算的,它是大量 Python 数学和科学计算包的基础。Pandas 库是充分借鉴了 NumPy 库的相关概念,所以要学好 Pandas 库就需要先掌握好 Numpy 库的用法。Numpy v1.0 发布于2006年,它的前身为 Numeric,Numpy 底层使用 C 语言编写,数组中直接存储对象,而不是存储对象指针,所以其运算效率远高于纯 Python 代码。
官方文档:https://numpy.org 官方中文文档:https://www.numpy.org.cn
章节目录
- ndarray 数组
- ndarray 索引
- Numpy 通用函数的介绍
- Numpy 的统计分析
- Numpy 案例:波士顿房价预测模型
致敬开源
大家好,欢迎你与我一同建设飞桨开源社区,知识分享是一种美德,让我们向开源致敬!
ndarray 数组
Python 中有 array 模块,但它不支持多维数组,无论是时列表还是 array 模块都没有科学运算函数,不适合做矩阵等科学计算。Numpy 没有使用 Python 本身的数组机制,而是提供了 ndarray 对象,该对象不仅能方便地存取数组,而且拥有丰富的数组计算函数。ndarray(多维数组)具有矢量运算能力,且快速、节省时间,可对整租数据进行快速运算的标准数学函数、线性代数、随机数生成等功能,是 Numpy 库的心脏。
数组创建
numpy.array(object,dtype=None,copy=True,order='K',subok=False,ndmin=0)
参数名称 | 说明 |
---|---|
object | 接收 array_like。表示想要创建的数组。无默认。 |
dtype | 接收 data-type。表示数组所需的数据类型。如果未给定,则选择保存对象所需的最小类型。默认为 None。 |
ndmin | 接收 int。指定生成数组应该具有的最小维数。默认为 None。 |
数组属性
ndarray(数组)是存储单一数据类型的多维数组。
属性 | 说明 |
---|---|
dtype | 返回 data-type,描述数组中元素的类型 |
itemsize | 返回 int,表示数组的每个元素的大小(以字节为单位) |
ndim | 返回 int,表示数组的维度 |
shape | 返回 tuple,表示数组的尺寸,对于 n 行 m 列的矩阵,形状为(n,m) |
size | 返回 int,表示数组的元素总数,等于数组形状的乘积 |
In [ ]
import numpy as np
a = np.array([1,2,3]) # 一维数组
b = np.array([[1,2,3]]) # 二维数组
c = np.array([[1,2,3],[4,5,6]]) # 二维数组
d = np.array([[1,2,3],[4,5,6],[7,8,9]]) # 二维数组
e = np.array([[[1,2,3]]]) # 三维数组
f = np.array([[[1,2,3],[4,5,6]]]) # 三维数组
g = np.array([[[1,2,3]],[[4,5,6]]]) # 三维数组
h = np.array([[[1,2,3],[4,5,6]],[[7,8,9]
,[10,11,12]],[[13,14,15],[16,17,18]]]) # 三维数组
# 查看数组的尺寸,其返回的是一个元组
print(a.shape)
print(b.shape)
print(c.shape)
print(d.shape)
print(e.shape)
print(f.shape)
print(g.shape)
print(h)
print(h.shape)
# 查看对象的类型
print(type(a))
# 查看数组的基础属性
print(a.itemsize)
print(a.dtype)
print(a.size)
print(a.ndim)
print(b.ndim)
print(h.ndim)
(3,)
(1, 3)
(2, 3)
(3, 3)
(1, 1, 3)
(1, 2, 3)
(2, 1, 3)
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]
[[13 14 15]
[16 17 18]]]
(3, 2, 3)
<class 'numpy.ndarray'>
8
int64
3
1
2
3
zeros函数、ones 函数
- 使用 zeros 函数创建元素全0的数组
- 使用 ones 函数创建元素全1的数组
In [ ]
# zeros 函数
np.zeros((3,4))
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
In [ ]
# ones 函数
np.ones((3,4))
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
eye函数、diag 函数
- 使用 eye 函数创建在对角线上为1的数组
- 使用 diag 函数创建为对角线上的元素赋值
In [ ]
# eye 函数
print(np.eye(3))
print(np.eye(3,4))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]]
In [ ]
# diag 函数
np.diag([1,2,3,4])
array([[1, 0, 0, 0],
[0, 2, 0, 0],
[0, 0, 3, 0],
[0, 0, 0, 4]])
ndarray 索引
单维数组的索引
Array: | 2 | 0 | 2 | 1 | 0 | 5 | 0 | 1 |
---|---|---|---|---|---|---|---|---|
正序索引: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
逆序索引: | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
In [ ]
import numpy as np
# 生成一个一维数组
arr1 = np.array([3,4,5])
print(arr1)
# 对第一个元素进行赋值
arr1[0] = 1.8
print(arr1)
# 啊咧咧,我明明赋值1.8,为什么打印的是1呢?
# print(np.float32(arr1))
[3 4 5]
[1 4 5]
In [ ]
# 打印浮点数的方法
arr2 = np.array([3,4,5], dtype='float64')
print(arr2)
arr2[0] = 2.8
print(arr2)
print(np.float32(arr2))
print(np.int32(arr2))
[3. 4. 5.]
[2.8 4. 5. ]
[2.8 4. 5. ]
[2 4 5]
逻辑型索引
In [ ]
arr3 = np.array([2.3,1.8,5.6])
print(arr3)
# 只打印True的元素
print(arr3[[True,True,False]])
# 逻辑型索引
index = arr3 > 2
print(index) # 返回boolean
print(arr3[index]) # 返回数组
[2.3 1.8 5.6]
[2.3 1.8]
[ True False True]
[2.3 5.6]
多维数组的索引
In [ ]
import numpy as np
# 生成一个一维数组
arr4 = np.arange(1,13)
print(arr4)
# 把一维数组变成三行四列的二维数组
arr4 = np.arange(1,13).reshape([3,4])
print(arr4)
print(arr4[2,3]) # 取出第三行第四个元素
print(arr4[2,:]) # 取出第三行(一维)
print(arr4[2:,:]) # 取出第三行(二维)
print(arr4[:,0]) # 取出第一列
print(arr4[1:3,1:3]) # 取出第二、三行与第二、三列
[ 1 2 3 4 5 6 7 8 9 10 11 12]
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
12
[ 9 10 11 12]
[[ 9 10 11 12]]
[1 5 9]
[[ 6 7]
[10 11]]
多维数组的逻辑型索引
In [ ]
import numpy as np
arr5 = np.arange(1,13).reshape([3,4])
print(arr5)
# 返回数组
print(arr5[arr5[:,0]>4,:])
# 返回boolean
print(arr5[:,0]>4)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[ 5 6 7 8]
[ 9 10 11 12]]
[False True True]
修改数组当中的元素
In [ ]
import numpy as np
arr6 = np.arange(1,13).reshape([3,4])
print(arr6)
# 修改第1行第1列的元素
arr6[0,0] = 0
print(arr6)
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[ 0 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
求解距离矩阵
随机在平面上生成100个点,求任意两点的欧式距离(直线距离),并将其保存。
- linspace 函数创建等差数列
- logspace 函数创建等比数列
In [ ]
import numpy as np
# 先平均切分10个点
n = 10
x = np.linspace(1, 100, n)
y = np.linspace(1, 100, n)
# 欧式距离计算公式
distance = np.sqrt((x[0] - x[1])**2 + (y[0] - y[1])**2)
print(x)
print(y)
print(distance)
[ 1. 12. 23. 34. 45. 56. 67. 78. 89. 100.]
[ 1. 12. 23. 34. 45. 56. 67. 78. 89. 100.]
15.556349186104045
In [ ]
# 求解距离矩阵
n = 100 # 样本个数
x = np.linspace(1, 100, n) # 样本的横坐标
y = np.linspace(1, 100, n) # 样本的纵坐标
dist = np.zeros([n,n])
# 计算欧式距离
for i in range(n):
for j in range(n):
dist[i,j] = np.sqrt((x[i] - x[j])**2 + (y[i] - y[j])**2)
print(x)
print(y)
print(dist)
[ 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. 39. 40. 41. 42.
43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56.
57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70.
71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84.
85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98.
99. 100.]
[ 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. 39. 40. 41. 42.
43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56.
57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70.
71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84.
85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98.
99. 100.]
[[ 0. 1.41421356 2.82842712 ... 137.17871555 138.59292911
140.00714267]
[ 1.41421356 0. 1.41421356 ... 135.76450199 137.17871555
138.59292911]
[ 2.82842712 1.41421356 0. ... 134.35028843 135.76450199
137.17871555]
...
[137.17871555 135.76450199 134.35028843 ... 0. 1.41421356
2.82842712]
[138.59292911 137.17871555 135.76450199 ... 1.41421356 0.
1.41421356]
[140.00714267 138.59292911 137.17871555 ... 2.82842712 1.41421356
0. ]]
Numpy 矩阵与通用函数
In [ ]
import numpy as np
matr1 = np.mat('1 2 3;4 5 6;7 8 9')
print(matr1)
print(type(matr1))
matr2 = np.matrix([[1,2,3],[4,5,6],[7,8,9]])
print(matr2)
print(type(matr2))
# np.bmat('matr1 matr2')
# print(type(np.bmat))
# 矩阵拼接
np.bmat('matr1 matr2; matr1 matr2')
# 矩阵转置
matr3 = matr1.T
print(matr3)
# 矩阵的逆
import numpy as np
# print(matr2.I) 会报错,因为不是满秩。
matr6 = np.matrix([[1,2,3],[4,5,6],[11,8,9]])
print(matr6)
print(matr6.I)
[[1 2 3]
[4 5 6]
[7 8 9]]
<class 'numpy.matrix'>
[[1 2 3]
[4 5 6]
[7 8 9]]
<class 'numpy.matrix'>
[[1 4 7]
[2 5 8]
[3 6 9]]
[[ 1 2 3]
[ 4 5 6]
[11 8 9]]
[[ 0.25 -0.5 0.25 ]
[-2.5 2. -0.5 ]
[ 1.91666667 -1.16666667 0.25 ]]
通用函数的介绍
In [ ]
arr1 = np.array([0.2, 0.4, 0.6])
arr2 = np.array([0.2, 0.6, 0.78])
list1 = [0.2, 0.4, 0.6]
# print(list1 + 1) # 非法操作
print(arr1 + 1)
print(arr1 * 2)
print(list1 * 2) # 返回的结果是打印list1两遍
print(arr1 + arr2) # 对应元素相加
print(arr1 * arr2) # 对应元素相乘
print(arr1 > 0)
print(arr1 < arr2)
# np.any函数和np.all函数返回布尔类型
print(arr1 == 0.2)
print(np.any(arr1 == 0.2)) # 逻辑or
print(np.all(arr1 == 0.2)) # 逻辑and
[1.2 1.4 1.6]
[0.4 0.8 1.2]
[0.2, 0.4, 0.6, 0.2, 0.4, 0.6]
[0.4 1. 1.38]
[0.04 0.24 0.468]
[ True True True]
[False True True]
[ True False False]
True
False
ufunc 函数的广播机制
In [ ]
# 一维数组的广播机制
arr3 = np.arange(1,13).reshape([4,3])
arr4 = np.array([1,2,3])
print(arr3)
print(arr4)
arr3 + arr4
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[1 2 3]
array([[ 2, 4, 6],
[ 5, 7, 9],
[ 8, 10, 12],
[11, 13, 15]])
In [ ]
# 二维数组的广播机制
arr3 = np.arange(1,13).reshape([4,3])
arr5 = np.array([[1],[2],[3],[4]])
print(arr5)
# arr3 + arr5
print(arr3 + arr5)
arr4 + arr5
[[1]
[2]
[3]
[4]]
[[ 2 3 4]
[ 6 7 8]
[10 11 12]
[14 15 16]]
array([[2, 3, 4],
[3, 4, 5],
[4, 5, 6],
[5, 6, 7]])
Numpy 进行统计分析
以二进制的形式对Numpy里的数组进行存储和读取
读取效率会更高
In [ ]
import numpy as np
arr1 = np.arange(1, 13).reshape([4, 3])
arr2 = np.arange(1, 13).reshape([3, 4])
print(arr1)
print(arr2)
np.save('./work/arr1.npy', arr1) # 保存数据
arr1_load = np.load('./work/arr1.npy') # 读取数据
print(arr1_load)
np.savez('./work/arr1&2.npz', arr1, arr2) # 保存多个数组数据
arr1_2_load = np.load('./work/arr1&2.npz')
print(arr1_2_load)
print(arr1_2_load.files) # 查看数据文件中有哪些数组对象
print(arr1_2_load['arr_0']) # 访问数据文件中的具体数组对象
print(arr1_2_load['arr_1']) # 访问指定数组 arr2
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
<numpy.lib.npyio.NpzFile object at 0x7f4b581df810>
['arr_0', 'arr_1']
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
In [ ]
# np.save 的解释文档
np.save?
# np.savez 的解释文档
# np.savez?
以txt的形式对Numpy里的数组进行存储和读取
- savetxt 函数是将数组写到某种分隔符隔开的文本文件中。
np.savetxt('./work/arr.txt',arr,fmt='%d',delimiter=',')
np.savetxt(保存的路径,要保存的对象,指定数据格式,指定同一行元素之间分割符号)
分割符号默认用空格分开。
- loadtxt 函数执行的是把文件加载到一个二维数组中。
np.loadtxt('./work/arr.txt',delimiter=',')
np.savetxt(保存的路径,要保存的对象,指定数据格式,指定同一行元素之间分割符号)
读取时使用的分割符号必须与保存时使用的分割符号时一致。
- genfromtxt 函数面向的是结构化数组和缺失数据。
np.genfromtxt('./work/arr.txt',delimiter=',')
In [ ]
np.savetxt('./work/arr1.txt', arr1) # 保存数据
np.loadtxt('./work/arr1.txt') # 读取数据
array([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]])
In [ ]
np.savetxt('./work/arr1.txt', arr1, delimiter=',')
np.loadtxt('./work/arr1.txt', delimiter=',')
# np.loadtxt('./work/arr1.txt', delimiter=' ') # 报错原因:分割符号不一致
array([[ 1., 2., 3.],
[ 4., 5., 6.],
[ 7., 8., 9.],
[10., 11., 12.]])
Numpy 的统计分析
排序
直接排序
sort 函数是最常用的排序方法:arr.sort()
。
sort 函数也可以指定一个 axis 参数,使得 sort 函数可以沿着指定轴对数据集进行排序,axis = 0
为沿纵轴排序;axis = 1
为沿横轴排序。
间接排序
- argsort 函数返回值为重新排序值的下标。
arr.argsort()
- lexsort 函数返回值是按照最后一个传入数据排序的。
arr.lexsort((a,b,c))
In [ ]
# help(np.sort)
In [ ]
# 使用数组进行简单统计分析
import numpy as np
# 直接排序
arr3 = np.random.randint(1,10,(3,4)) # 随机生成一个从1到9的三行四列数组
print(arr3)
arr3.sort(axis=0) # 对数组每一列的元素按大小进行排序
print(arr3)
arr3.sort(axis=1) # 对数组每一行的元素按大小进行排序
print(arr3)
[[1 6 5 5]
[3 9 8 1]
[2 8 1 6]]
[[1 6 1 1]
[2 8 5 5]
[3 9 8 6]]
[[1 1 1 6]
[2 5 5 8]
[3 6 8 9]]
In [ ]
# 间接排序
arr4 = np.random.randint(1,10,(3,4))
print(arr4)
print(arr4.argsort(axis=0)) # 返回按列排序后的下标
arr5 = np.random.randint(1,10,(3,4))
print(arr5)
print(arr5.argsort()) # 返回按行排序后的下标,默认 axis=1
[[9 5 4 1]
[4 6 1 3]
[4 9 2 4]]
[[1 0 1 0]
[2 1 2 1]
[0 2 0 2]]
[[4 4 8 1]
[2 1 5 8]
[4 3 8 3]]
[[3 0 1 2]
[1 0 2 3]
[1 3 0 2]]
数据去重和重复数据
数据去重
通过 unique 函数可以找出数组中唯一值并返回已排序的结果。
重复数据
tile 函数 np.tile(arr,repeats)
,参数arr
指定重复的数组,参数repeats
指定重复的次数。
repeat 函数 np.repeat(arr,repeats,axis=None)
,参数arr
是需要重复的数组元素,参数repeats
是重复次数,参数axis
指定沿着哪个轴进行重复,axis=0
表示按行进行元素重复;axis=1
表示按列进行元素重复。
“tile 函数”与“repeat 函数”的区别在于,tile 函数是对数组进行重复操作,repeat 函数是对数组中的每个元素进行重复操作。
In [ ]
# 对数组进行去重操作
arr6 = np.random.randint(1,10,(3,4))
print(arr6)
np.unique(arr6)
[[8 8 8 6]
[2 6 5 9]
[9 5 3 7]]
array([2, 3, 5, 6, 7, 8, 9])
In [ ]
arr7 = np.random.randint(1,10,(3,4))
print(arr7)
print(np.tile(arr7,2)) # 对数组进行复制操作
print(np.repeat(arr7,2,axis=1)) # 对数组元素进行复制操作
[[6 8 5 5]
[8 9 6 2]
[8 7 4 5]]
[[6 8 5 5 6 8 5 5]
[8 9 6 2 8 9 6 2]
[8 7 4 5 8 7 4 5]]
[[6 6 8 8 5 5 5 5]
[8 8 9 9 6 6 2 2]
[8 8 7 7 4 4 5 5]]
常用的统计函数
当axis=0
时,表示沿着纵轴计算;axis=1
时,表示沿着横轴计算;默认时计算一个总值。
函数 | 说明 |
---|---|
sum | 计算数组的和 |
mean | 计算数组均值 |
std | 计算数组标准差 |
var | 计算数组方差 |
min | 计算数组最小值 |
max | 计算数组最大值 |
argmin | 返回数组最小元素的索引 |
argmax | 返回数组最大元素的索引 |
cumsum | 计算所有元素的累计和 |
cumprod | 计算所有元素的累计积 |
In [ ]
arr8 = np.random.randint(1,10,(3,4))
print(arr8)
print(arr8.mean()) # 统计数组所有元素的均值
print(arr8.mean(axis=0)) # 按列统计数组的均值
print(arr8.max(axis=0)) # 按列统计数组的最大值
print(arr8.argmax(axis=0)) # 找出每列元素最大值的位置
[[5 7 2 1]
[1 9 1 7]
[9 7 7 8]]
5.333333333333333
[5. 7.66666667 3.33333333 5.33333333]
[9 9 7 8]
[2 1 2 2]
Numpy 案例:波士顿房价预测模型
波士顿房价影响因素示意图
学有余力的同学,可以先看看此节,当作学习深度学习前的热身吧。你会发现 PaddlePaddle 实现的程序框架、计算跟 Numpy 库实现的程序是惊人的相似。
关于Python的技术储备
在这里给大家分享一些免费的课程供大家学习,下面是课程里面的截图,扫描最下方的二维码就能全部领取,如果图片失效点击蓝色字体便可跳转哦~点这里哦
1.Python所有方向的学习路线
2.学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
3.学习资料
4.实战资料
实践是检验真理的唯一标准。这里的压缩包可以让你再闲暇之余帮你提升你的个人能力。
5.视频课程
好啦今天的分享就到这里结束了,快乐的时光总是短暂呢,想学习更多课程的小伙伴不要着急,有更多惊喜哦~