Numpy全名“Numeric Python”(数字python),是非常重要的python第三方扩展包,主要用来处理数组。pandas, sklearn等工具包当中都大量使用了Numpy的函数。由此可见,我们对于Numpy的学习是很有必要的。
数组(array)有别于python数据结构中的列表(list)。因为我们在实际项目如计算机视觉中处理的数据一般都是图片,是矩阵结构,矩阵最大的特点就是向量化操作。在python中数组可以实现向量化的操作,而列表并不具备这个功能。
我们可以通过列表来创建数组。
示例:
# 导入Numpy包并将其命名为np,后面就省略了
import numpy as np
# 创建一维数组
list_1 = [0, 1, 2, 3]
arr_1 = np.array(list_1)
print(arr_1)
输出:
[0 1 2 3]
# 创建二维数组
arr_2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print('二维数组:\n', arr_2)
# 创建三维数组
arr_3 = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]])
print('三维数组:\n', arr_3)
输出:
二维数组:
[[1 2 3]
[4 5 6]
[7 8 9]]
三维数组:
[[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]]
[[10 11 12]
[13 14 15]
[16 17 18]]]
可以看到,我们通过多维列表创建了一个多维数组。对于更高维数组的创建也是同理。如果数组维度过高我们很难一眼看出来是几维的怎么办呢?这里我们可以观察数组最左边或者是最右边的方括号个数,比如arr_3的最左边是三个方括号,那么我们可以确定,这是三维数组。
如果我们想创建其他类型的数组怎么办呢?我们可以通过dtype参数来规定数组的类型。
示例:
# 创建float类型的数组
arr_f = np.array([1, 2, 3, 4], dtype='float')
print(arr_f)
输出:
[1. 2. 3. 4.]
数组中的数字带上了小数点,说明了我们的数字是浮点型的(float)。
当然,我们也可以更改数组中数据的类型。通过调用astype方法就可以实现。
示例:
# 创建float类型的数组
arr_f = np.array([1, 2, 3, 4], dtype='float')
# 将类型转换为int类型
arr_f2i = arr_f.astype('int')
print(arr_f2i)
输出:
[1 2 3 4]
可以看到,数组中的数字已经不带有小数点了,说明数字现在是整型(int)。
其他一些类型转换的例子:
# 创建float类型的数组
arr_f = np.array([0, 1, 2, 3, 4], dtype='float')
# 将类型转换为str类型
arr_f2s = arr_f.astype('str')
print(arr_f2s)
# 将类型转换为bool类型
arr_f2b = arr_f.astype('bool')
print(arr_f2b)
输出:
['0.0' '1.0' '2.0' '3.0' '4.0']
[False True True True True]
数组的一个特点就是数组中的数据都得是同一类型的,但是如果我们想让一个数组包含不同类型的数据,我们可以将dtype参数设置为’object’。
示例:
# 使数组包含不同类型的数据
arr_o = np.array([0, '1', 'a', True], dtype='object')
print(arr_o)
输出:
[0 '1' 'a' True]
通过学习创建数组,我们知道了数组是有维度的,是有类型的,那么我们如何快速地查看数组的属性呢?
示例:
# 创建一个二维数组
arr_2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr_2)
# 输出形状shape
print('shape: ', arr_2.shape)
# 输出数组类型dtype
print('datatype: ', arr_2.dtype)
# 输出数组大小size
print('size: ', arr_2.size)
# 输出数组维度ndim
print('num dimensions: ', arr_2.ndim)
输出:
[[1 2 3]
[4 5 6]
[7 8 9]]
Shape: (3, 3)
Datatype: int32
Size: 9
Num Dimensions: 2
这里输出结果告诉我们,这个数组的形状是3行3列的, 数据类型是int类型32位, 大小为3 x 3 = 9,维度数为2。
数组的索引和列表相似,都是从0开始,在方括号内写索引的。数组索引的书写顺序遵循从高维到低维的规则。
示例:
arr1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# 提取单一数据
print('提取单一数据:\n', arr1[0, 1])
# 切片提取数据,左面不省略
print('切片提取数据,左面不省略:\n', arr1[0:2, 1:3])
# 切片提取数据,左面省略
print('切片提取数据,左面省略:\n', arr1[:2, :3])
# 设定步长提取数据,步长为2
print('设定步长提取数据,步长为2:\n', arr1[::2, ::2])
# 设定步长提取数据,步长为-1,相当于反转数组
print('反转数组:\n', arr1[::-1, ::-1])
输出:
提取单一数据:
2
切片提取数据,左面不省略:
[[2 3]
[6 7]]
切片提取数据,左面省略:
[[1 2 3]
[5 6 7]]
设定步长提取数据,步长为2:
[[ 1 3]
[ 9 11]]
反转数组:
[[12 11 10 9]
[ 8 7 6 5]
[ 4 3 2 1]]
冒号":"表示省略。
当切片区间左边省略时,默认从0开始。
切片区间遵循左闭右开的规则。
arr1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# 计算平均值
print('计算平均值:\n', arr1.mean())
# 计算最大值
print('计算最大值:\n', arr1.max())
# 计算最小值
print('计算最小值:\n', arr1.min())
# 重构数组
print('重构数组:\n', arr1.reshape(2, 6))
# 拉直数组
print('拉直数组:\n', arr1.flatten())
输出:
计算平均值:
6.5
计算最大值:
12
计算最小值:
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]
这里拉直的方法在全连接神经网络中会经常用到。
利用arange函数生成等差数列:
# 生成从0到4的等差数列,差值默认为1
print('生成从0到4的等差数列:\n', np.arange(5))
# 生成从0到4的等差数列,差值默认为1
print('生成从0到4的等差数列:\n', np.arange(0, 5))
# 生成从0到4的等差数列,差值为2
print('生成从0到4的等差数列,差值为2:\n', np.arange(0, 5, 2))
# 生成从5到1的等差数列,差值为-1
print('生成从5到1的等差数列,差值为-1:\n', np.arange(5, 0, -1))
输出:
生成从0到4的等差数列:
[0 1 2 3 4]
生成从0到4的等差数列:
[0 1 2 3 4]
生成从0到4的等差数列,差值为2:
[0 2 4]
生成从5到1的等差数列,差值为-1:
[5 4 3 2 1]
使用linspace函数生成固定个数的数组:
# 生成从1到20的数列
print(np.linspace(start=1, stop=20, num=10, dtype=int))
输出:
[ 1 3 5 7 9 11 13 15 17 20]
生成全0全1数组
# 生成全0数组
print(np.zeros([3, 3]))
# 生成全1数组
print(np.ones([3, 3]))
输出:
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
生成随机数
# 设置随机数种子
np.random.seed(0)
# 生成0到1之间的均匀分布
arr1 = np.random.rand(2, 3)
print('np.random.rand(2, 3):\n', arr1)
# 生成0到1之间的均匀分布
arr1 = np.random.random((2, 3))
print('np.random.random((2, 3)):\n', arr1)
# 生成取值范围为[5, 10)的数组
arr1 = np.random.randint(low=5, high=10, size=(2, 3), dtype='int')
print('np.random.randint(low=5, high=10, size=(2, 3), dtype="int"):\n', arr1)
# 生成符合标准正态分布的数组
arr1 = np.random.randn(2, 3)
print('np.random.randn(2, 3):\n', arr1)
# 生成符合指定分布的正态分布,loc为均值,scale为标准差
arr1 = np.random.normal(loc=0, scale=1, size=(2, 3))
print('np.random.normal(loc=0, scale=1, size=(2, 3)):\n', arr1)
# 随机打乱
arr1 = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr1)
print('np.random.shuffle(arr1)随机打乱:\n', arr1)
输出:
np.random.rand(2, 3):
[[0.5488135 0.71518937 0.60276338]
[0.54488318 0.4236548 0.64589411]]
np.random.random((2, 3)):
[[0.43758721 0.891773 0.96366276]
[0.38344152 0.79172504 0.52889492]]
np.random.randint(low=5, high=10, size=(2, 3), dtype="int"):
[[5 6 6]
[5 6 9]]
np.random.randn(2, 3):
[[ 0.44386323 0.33367433 1.49407907]
[-0.20515826 0.3130677 -0.85409574]]
np.random.normal(loc=0, scale=1, size=(2, 3)):
[[-2.55298982 0.6536186 0.8644362 ]
[-0.74216502 2.26975462 -1.45436567]]
np.random.shuffle(arr1)随机打乱:
[4 3 2 5 1]