NumPy 是在1995年诞生的 Python 库 Numeric 的基础上建立起来的,但真正促使 NumPy 的发行的是 Python 的 SciPy 库。但 SciPy 中并没有合适的类似于 Numeric 中的对于基础数据对象处理的功能。于是, SciPy 的开发者将 SciPy 中的一部分和 Numeric 的设计思想结合,在 2005 年发行了 NumPy。
科学计算包 NumPy 是 Python 的一种开源的数值计算扩展库。它包含很多功能,如创建 n 维数组(矩阵)、对数组进行函数运算、数值积分等。 NumPy 的诞生弥补了这些缺陷,它提供了两种基本的对象:
ndarray :是储存单一数据类型的多维数组。
ufunc :是一种能够对数组进行处理的函数。
NumPy 常用的导入格式: import numpy as np
一、创建数组对象
通常来说, ndarray 是一个通用的同构数据容器,即其中的所有元素都需要相同的类型。利用 array 函数可创建 ndarray 数组。
(一)利用array函数创建数组对象
array 函数的格式: np.array(object, dtype, ndmin)
array 函数的主要参数及说明:
参数名称 | 说明 |
object | 接收 array ,表示想要创建的数组 |
dtype | 接收 data-type ,表示数组所需的数据类型,未给定则选择保存对象所需的最小类型,默认为 None |
ndmin | 接收 int ,制定生成数组应该具有的最小维数,默认为 None |
import numpy as np data1 = [1,3,5,7] # 列表 w1 = np.array(data1) print('w1:',w1) data2 = (2,4,6,8) # 元组 w2 = np.array(data2) print('w2:',w2) data3 = [[1,2,3,4],[5,6,7,8]] # 多维数组 w3 = np.array(data3) print('w3:',w3)
输出:
w1: [1 3 5 7] w2: [2 4 6 8] w3: [[1 2 3 4] [5 6 7 8]]
(二)专门创建数组的函数
1、arange 函数:创建等差一维数组
格式: np.arange(start, stop, step, dtype)
参数名称 | 说明 |
start | 起始值,可省略,默认从 0 开始; |
stop | 结束值;生成的元素不包括结束值; |
step | 步长,可省略,默认步长为1; |
dtype | 设置元素的数据类型,默认使用输入数据的类型。 |
a1 = np.arange(10) print('a1:',a1) a2 = np.arange(1,10,2) print('a2:',a2) print(a2.dtype) # 元素类型是int32
输出:
a1: [0 1 2 3 4 5 6 7 8 9] a2: [1 3 5 7 9] int32
2、linspace 函数:创建等差一维数组,接收元素数量作为参数。
格式: np.linspace(start, stop, num, endpoint, retstep=False, dtype=None)
参数名称 | 说明 |
start | 起始值,默认从 0 开始; |
stop | 结束值;生成的元素不包括结束值; |
num | 要生成的等间隔样例数量 |
a3 = np.linspace(0,100,11) # 注意:连同首尾共11个端点,10个区间(最后一个参数表示数组中元素的数量) print('a3:',a3) print(a3.dtype) # 元素类型是float64
输出:
a3: [ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.] float64
3、logspace 函数:创建等比一维数组
格式: np.logspace(start, stop, num, endpoint=True, base=10.0, dtype=None)
logspace 的参数中, start, stop 代表的是 10 的幂,num 代表要生成的元素数量,默认基数 base 为 10 。
a4 = np.logspace(1,3,3) # 参数含义与linespace相同,但这些元素将作为指数出现,默认底数是10 print('a4:',a4) a5 = np.logspace(1,3,3,base=3) # 修改底数为3 print('a5:',a5)
输出:
a4: [ 10. 100. 1000.] a5: [ 3. 9. 27.]
4、ones 函数:创建指定长度或形状的全 1 数组
格式: np. ones(shape, dtype=None, order='C')
a6 = np.ones((3,4)) # 参数(3,4)用于指定形状,相当于np.ones(shape=(3,4)) print(a6)
输出:
[[ 1. 1. 1. 1.] [ 1. 1. 1. 1.] [ 1. 1. 1. 1.]]
5、zeros 函数:创建指定长度或形状的全 0 数组
格式: np.zeros(shape, dtype=float, order='C')
a7 = np.zeros((3,3)) print(a7)
输出:
[[ 0. 0. 0.] [ 0. 0. 0.] [ 0. 0. 0.]]
np.zeros_like函数
a8 = np.zeros_like(a6) # 用已有数组的形状来创建新数组常使用*_like函数 print(a8)
输出:
[[ 0. 0. 0. 0.] [ 0. 0. 0. 0.] [ 0. 0. 0. 0.]]
6、full 函数:根据指定形状,并用同一参数填充的新数组
格式:np.full(shape, fill_value, dtype=None, order='C')
a9 = np.full((2,4),5) # 第1个参数(2,4)指明了形状,第2个参数给出了元素值 print(a9) # 等价于5*np.ones((2,4))
输出:
[[5 5 5 5] [5 5 5 5]]
7、identity 函数:用于创建一个 n ∗ n n*nn∗n 的单位矩阵(主对角线元素全为1,其余全为0的矩阵)
格式:np.identity(n, dtype=float)
b1 = np.identity(3) # 必须是n阶方阵,而且1只能在主对角线上 print(b1)
输出:
[[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
8、eye 函数:返回一个N×M阶的矩阵(k所代表的对角线为上的元素1)
格式:np.eye(N,M=None, k=0, dtype=<class 'float'>, order='C)
参数名称 | 说明 |
N | int型,代表返回的矩阵的行数是N |
M | int型,代表返回的矩阵的列数是M(默认是None) |
k | int型,k=0代表是主对角线,k每增加1就往上移动一位对角线,k每减小1就往下移动一位对角线。(默认是0,即主对角线) |
dtype | 数组元素的类型,默认为float64 |
b2 = np.eye(3) # 与上面相同,相当于np.eye(3,k=0) 参数k=0表示元素1出现主对角线上 print(b2)
输出:
[[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
虽然 eye 函数和 identity 函数都能创建单位阵,但 eye比 identity 更灵活,见下面。
元素1都出现在主对角线之上:
b3 = np.eye(3,k=1) # 元素1都出现在主对角线之上 print(b3)
输出:
[[ 0. 1. 0.] [ 0. 0. 1.] [ 0. 0. 0.]]
元素1都出现在主对角线之下:
b4 = np.eye(3,k=-1) # 元素1都出现在主对角线之下 print(b4)
输出:
[[ 0. 0. 0.] [ 1. 0. 0.] [ 0. 1. 0.]]
前2个参数用于指定形状,可以不是方阵:
b5 = np.eye(3,4,k=1) print(b5)
输出:
[[ 0. 1. 0. 0.] [ 0. 0. 1. 0.] [ 0. 0. 0. 1.]]
9、diag 函数:创建一个对角阵
格式: np.diag(v, k=0)
列表作为参数指定了对角线的元素:
b6 = np.diag([5,6,7]) print(b6)
输出:
[[5 0 0] [0 6 0] [0 0 7]]
diag 是 eye 的推广,允许指定对角线的元素是非1的值:
b7 = np.diag([5,6,7],k=1) print(b7)
输出:
[[0 5 0 0] [0 0 6 0] [0 0 0 7] [0 0 0 0]]
二、ndarray对象属性和数组转置
(一)数组对象属性
属性 | 说明 |
ndim | 返回数组的轴的个数 |
shape | 返回数组的维度 |
size | 返回数组元素个数 |
dtype | 返回数据类型 |
itemsize | 返回数组中每个元素的字节大小 |
c1 = np.array([1,2,3,4]) print('秩为:',c1.ndim) print('形状为:',c1.shape) # 结果显示的(4,)不应该理解为沿轴0有4行,而应该理解为沿着唯一的维度(其实是轴1)方向有4个元素 print('元素个数为:',c1.size) print('数据类型为:',c1.dtype) print('每个元素的字节大小:',c1.itemsize) print(c1.nbytes) type(c1) # 最后一个不用print就可以输出
输出:
秩为: 1 形状为: (4,) 元素个数为: 4 数据类型为: int32 每个元素的字节大小: 4 16 numpy.ndarray
(二)数组的转置
1、一维数组的转置还是它本身
c2 = c1.T print(c2.shape) c2
输出:
(4,) array([1, 2, 3, 4])
2、二维数组的转置
c3 = np.array([[1],[2],[3]]) # 形状为(3,1)的列向量 print(c3) print(c3.shape) c4 = c3.T # 转置后变成形状为(1,3)的行向量 print(c4) print(c4.shape)
输出:
[[1] [2] [3]] (3, 1) [[1 2 3]] (1, 3)
三、生成随机数组
(一)通过random模块创建随机数组
在 NumPy.random 模块中,提供了多种随机数的生成函数。如 randint 函数生成指定范围的随机整数来构成指定形状的数组。注意:涉及到区间时均是左闭右开。
用法:np.random.randint(low, high = None, size = None)
1、设定随机数种子,这样每次运行的数据都相同。
np.random.seed(666)
2、产生[0,1)范围内的5个随机小数构成的一维数组。
d1 = np.random.random(5) print(d1)
输出:
[ 0.70043712 0.84418664 0.67651434 0.72785806 0.95145796]
3、产生[0,1)范围内的随机小数构成的二维数组。
d2 = np.random.random((2,3)) # 此处需要使用元组,与下面的rand函数不同 d2
输出:
array([[ 0.0127032 , 0.4135877 , 0.04881279], [ 0.09992856, 0.50806631, 0.20024754]])
4、产生[1,100)范围内的6个随机整数构成的一维数组。
d3 = np.random.randint(1,100,6) print(d3)
输出:
[40 70 83 77 80 14]
5、产生[1,100)范围内的随机整数构成的二维数组。
d4 = np.random.randint(1,100,(2,3)) d4
输出:
array([[70, 21, 12], [25, 21, 37]])
random模块的常用随机数生成函数:
函数 | 说明 |
seed | 确定随机数生成器的种子 |
permutation | 返回一个序列的随机排列或返回一个随机排列的范围,不会改变原数组 |
shuffle | 对一个序列进行随机排序,会改变原数组 |
binomial | 产生二项分布的随机数 |
normal | 产生正态(高斯)分布的随机数 |
beta | 产生 beta 分布的随机数 |
chisquare | 产生卡方分布的随机数 |
gamma | 产生 gamma 分布的随机数 |
uniform | 产生在 [0,1) 中均匀分布的随机数 |
(二)分布函数
下面四个与分布有关,其中前两个分布函数是后两个的简化形式。
1、产生[0,1)范围且服从均匀分布的随机小数构成的数组
d5 = np.random.rand(2,3) # 此处数组形状不能使用元组,与上面的random函数不同 print(d5)
输出:
[[ 0.8578588 0.76741234 0.95323137] [ 0.29097383 0.84778197 0.3497619 ]]
2、产生服从标准正态分布(均值为0、标准差为1)的随机小数构成的数组
d6 = np.random.randn(2,3) # 此处数组形状不能使用元组,与上面的random函数不同 print(d6)
输出:
[[-0.21326813 0.44076692 0.69339587] [ 0.03820097 -0.18592982 -0.35371521]]
3、产生[a,b)范围内的均匀分布数组
d7 = np.random.uniform(1,11,(2,3)) # 此处数组形状需要使用元组 print(d7)
输出:
[[ 5.67585496 4.15815319 4.90162586] [ 3.68329811 8.53663841 7.66737465]]
4、产生更一般的正态分布(均值为a,标准差为b)数组
d8 = np.random.normal(5,2,(2,3)) # 此处数组形状需要使用元组 print(d8)
输出:
[[ 5.12204808, 7.15712276, 3.40432856], [ 7.3402652 , 5.22424341, 5.06370777]]
(三)choice函数
choice 函数原型:numpy.random.choice(a, size=None, replace=True, p=None)
choice 函数表示从给定一维数组 a 或由 n 确定的 arange(n) 数列中以一定概率 p 随机采样 size 次,当 replace 为 True 时表示有放回取样(取样元素可能重复),否则是不放回取样(取样元素不会重复)。
d9 = np.random.choice(5,3) # 从整数0~4中均匀采样,并且可以有重复元素 print(d9) d10 = np.random.choice(5,3,replace=False,p=[0,0.2,0.3,0.4,0.1]) # 以指定概率不重复采样 print(d10) ls = ['a','b','c','e','f','g'] d11 = np.random.choice(ls,5,p=[0.15,0.15,0.2,0.05,0.2,0.25]) d11
输出:
[0 3 3] [3 2 4] array(['f', 'f', 'b', 'f', 'f'], dtype='<U1')
(四)随机排序
1、shuffle 函数
shuffle 函数会修改原数组。
print(d3) # 输出排序前的c3 np.random.shuffle(d3) print(d3) # 输出排序后的c3,发现shuffle函数会修改原数组
输出:
[40 70 83 77 80 14] [77 70 14 80 40 83]
2、permutation 函数
permutation 函数不会改变原数组,而会创建一个新数组。
d12 = np.random.permutation(d3) # permutation不会改变原数组,而会创建一个新数组 print(d3) d12
输出:
[77 70 14 80 40 83] array([83, 80, 77, 40, 14, 70])