认识NumPy数组对象
Numpy中最重要的一个特点就是其N维数组特点,即
ndarray
对象
ndarray对象的常用属性
属性 | 具体说明 |
---|---|
ndarray.ndim | 维度个数,也就是数轴的个数,如一维,二维,三维等 |
ndarray.shape | 数组的维度,这是一个整数的元组,表示每个维度上数组的大小,例如,一个n行n列的数组,它的shape属性为(n,m) |
ndarray.size. | 数组元素的个数,等于shape属性中元组元素的乘积 |
ndarray.dtype | 描述数组中元素类型的对象 |
ndarray.itemsize | 数组中每个元素的字节大小 |
创建NumPy数组
array()
函数
import numpy as np
data = np.array([1,2,3]) #可以传入列表、元组等
zeros()
函数创建元素值都是0的数组
data = np.zeros((3,4))
# array([[0.,0.,0.,0.,],
# [0.,0.,0.,0.,],
# [0.,0.,0.,0.]])
-
ones()
函数创建元素值都为1的数组,效果和zeros()类似,不演示
-
使用
empty()
函数创建一个新的数组,该数组只分配了内存空间,它里面的元素的随机的,且数据默认类型为float64
np.empty((3,3))
# array([[0.00000000e+000, 0.00000000e+000, 0.00000000e+000],
# [0.00000000e+000, 0.00000000e+000, 2.60866661e-321],
# [8.34448532e-308, 0.00000000e+000, 3.91792476e-317]])
#但是不知道为什么传入(3,2)时,其中的元素都是0,而不是随机数
data = np.empty((3,2))
# array([[0., 0.],
# [0., 0.],
# [0., 0.]])
- 通过
arrange()
函数可以创建一个数组
np.arrange(4) # 0~3 不包括4
# array([0,1,2,3])
np.arrange(1,20,5) #1 到 20,步长为 5
# array([ 1, 6, 11, 16])
ndarray对象的数据类型
查看数据类型
ndarray.dtype
可以创建一个表示数据类型的对象。想要获取数据类型,有如下方法:
data = np.array([1,2,3])
data.dytpe # dtype('int32')
data.dtype.name # 'int32'
转化数据类型
ndarray 对象可以通过直接对 dtype 属性赋值,或者使用 astype()
方法进行转化
data = np.array([1,2,3])
data.dtype = 'float64'
# 或
# data.astype(np.float64)
数组运算
矢量化运算
大小相同的数组之间的任何算数运算都会应用到元素级,即只用于位置相同的元素之间,所得的结果组成一个新的数组,如下图所示:
这种运算规则同样适用于其他运算
数组广播
数组在进行矢量化运算时,要求数组的形状是相等的。当形状不相等的数组执行算数运算的时候,就会出现广播机制,该机制会对数组进行扩展,使数组的shape属性一样,这样就可以进行矢量化运算了
arr1 = np.array([[0],[1],[2],[3]])
arr1.shape # (4,1)
arr2 = np.array([1,2,3])
arr2.shape # (3,) 只有一个维度,元素有3个
arr1 + arr2
# array([1,2,3],
# [2,3,4],
# [3,4,5],
# [4,5,6])
arr1 + arr2
注意:广播机制实现了对两个或两个以上数组的运算,即使这些数组的shape不是完全相同的,只需要满足如下任意一个条件即可。
(1) 数组的某一维度等长。
(2) 其中一个数组的某一维度为1
广播机制需要扩展维度小的数组,使得它与最大维度的数组的shape值相同,以便使用元素级函数或者运算符进行运算
数组与标量间的运算
用数组中的每一个元素与标量进行运算
data = np.array([1,2,3])
data + 1
# array([2,3,4])
ndarray的索引和切片
一维数组切片
arr = np.array([0,1,2,3,4,5,6,7])
arr[5] #获定索引为 5 的元素
# 5
arr[:5] # 从头开始获取到索引为 5 的元素,但不包括 5
# array([0,1,2,3,4])
arr[3:5] #获取索引为 3 ~ 5 的元素,但不包括 5
#array([3,4])
arr[1:6:2] # 第三个参数指定步长,每隔几取值
# array([1,3,5])
多维数组切片
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
# array([[1,2,3],
# [4,5,6],
# [7,8,9]])
arr[1] #获取行索引为1的元素
# array([4,5,6])
arr[0,1] # 获取位于第 0 行第 1 列的元素
# 2
arr[:2] # 从头开始获取行到第行索引为 2 的行,但不包括 索引为 2 的行
# array([[1,2,3],
# [4,5,6]])
arr[0:2,0:2] # 行 0 ~ 2 ,列 0 ~ 2,但都不包括索引为 2 的行和列
# array([[1,2],
# [4,5]])
arr[1, :2] # 第 1 行, 从头取列索引到 2 的元素,不包括索引为 2 的列
# array([4,5])
数组索引
传入一个数组,则表示索引多个行。
传入两个数组,第一个作为行索引,第二个作为列索引
arr = np.arange(16).reshape(4,4)
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
arr[[1,2]] # 传入一个数组
# array([4,5,6,7],
# [8,9,10,11])
arr[[1,3],[1,2]] #传入两个数组
#array([5,14])
布尔型索引
布尔型索引指的是将一个布尔数组作为索引,返回的数据是布尔数组中True对应位置的值。
student_name = np.array(['Tom','Lily','Jack','Rose'])
student_score = np.array([[79,88,80],[89,90,92],[83,78,85],[78,76,80]])
student_name == 'Jack' # array([False,False,True,False])
student_score[student_name == 'Jack'] # array([[83,78,85]])
数组的转置和轴对称
数组的轴
也可以理解为数组的维度
数组的轴编号
数组结构从外向内,数组每一个维度算作一个轴,从0开始递增(个人理解)
如图,从外往内数维度的编号从0开始不断加1
该数组的轴编号和维度的对应
shape属性和维度与轴编号的关系
shape属性可以体现维度个数和维度上面的元素个数,shape的顺序是按照轴编号从0开始的
shape 为 (3,) 表示只有一个维度,轴编号为 0 的 维度上有3个元素
shape 为 (3,3) 表示有两个维度,轴编号为 0 的维度上有3个元素,编号为1 的轴所对应的维度上有3个元素
数组转置的方法
transpose()
方法,里面传入轴的顺序编号,对它的shape中的顺序进行调换
arr = np.array([[1,2,3],[4,5,6]])
arr.transpose(1,0) # 编号为 1 的轴和编号为 0 的轴对调
# array([[1, 4],
# [2, 5],
# [3, 6]])
T属性
进行简单的转换
arr = np.array([[1,2,3],[4,5,6]])
arr.T
# array([[1, 4],
# [2, 5],
# [3, 6]])
swapaxes()
转换其中的两个轴
arr = np.array([[1,2,3],[4,5,6]])
arr.swapaxes(1,0)
# array([[1, 4],
# [2, 5],
# [3, 6]])
NumPy辑运算之where()函数
NumPy的where()
函数是三元运算表达式 x if condition else y
的矢量化版本
where(arr_con, arr_x, arr_y)
# arr_con 表示判断条件
# 当取出的元素为 True 时从 arr_x 中取值
# 为 False 时则从 arr_y 中取值
arr_x = np.array([1,2,3])
arr_y = np.array([4,5,6])
arr_con = np.array([True,False,False])
np.where(arr_con, arr_x, arr_y) #array([1,5,6])
数组统计运算
方法 | 描述 |
---|---|
sum | 对数组中全部或某个轴的元素求和 |
mean | 算数平均值 |
min | 计算数组中的最小值 |
max | 计算数组中的最大值 |
argmin | 表示最小值的索引 |
argmax | 表示最大值的索引 |
cumsum | 所有元素的累计和 |
cumprod | 所有元素的累计和 |
格式:
arr = np.array([1,2,3,4])
arr.sum() #其他方法类似格式
数组排序
sort()
方法实现,注意:会修改数组本身
arr = np.array([1,3,2,5,4])
# 从小到大排序
arr.sort() # array([1,2,3,4,5])
# 对某一个轴上的元素进行排序
arr.sort(0) #对轴编号为 0 的元素进行排序
唯一化和其他集合逻辑
函数 | 描述 |
---|---|
unique(x) | 计算x中的唯一元素 |
interset1d(x,y) | 计算 x 和 y 中的公共元素,并返回有序结果 |
union1d(x,y) | 计算 x 和 y 中的并集,并返回有序结果 |
in1d(x,y) | 得到一个表示"x的元素是否包含y"的布尔型数组 |
setdiff1d(x,y) | 集合的差,即元素在 x 中且不在 y 中 |
setxor1d(x,y) | 集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素 |
线性代数模块
numpy.linalg模块的常见函数
函数 | 描述 |
---|---|
dot | 矩阵乘法 |
diag | 以一维数组的形式返回方阵的对角线,或将一维数组转为方阵 |
trace | 计算对角线元素和 |
det | 计算矩阵的行列式 |
eig | 计算方阵的特征值和特征向量 |
inv | 计算方阵的逆 |
qr | 计算qr分解 |
svd | 计算奇异值 |
solve | 解线性方程Ax=b,其中 A 是一个方阵 |
lstsq | 计算Ax=b的最小二乘解 |
随机数模块random模块
函数 | 描述 |
---|---|
seed | 生成随机数的种子 |
rand | 产生均匀分布的样本值 |
randint | 从给定的上下限范围内随机选取整数 |
normal | 产生正态分布的样本值 |
beta | 产生Beta分布的样本值 |
uniform | 产生在[0,1]中的均匀分布的样本值 |
rand()
np.random.rand(3,3) #随机生成一个 3 行 3 列的二维数组
np.random.rand(2,3,3) #随机生成一个shape 为(2, 3, 3)三维数组
seed()
函数
seed()
函数可以保证生成的随机数具有可预测性,也就是说产生的随机数相同,它的语法格式如下:
numpy.random.seed(seed=None)
上述函数只有一个seed参数,用于指定随机数生成时所用算法开始时的整数值。当调用seed()函数时,如果传递给seed参数的值相同,则每次生成的随机数都是一样的。如果不传递参数值,则系统会根据时间来自己选择值,此时每次生成的随机数会因为时间差异而不同
np.random.seed(0)
np.random.rand(5)
# array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed(0)
np.random.rand(5)
# array([0.5488135 , 0.71518937, 0.60276338, 0.54488318, 0.4236548 ])
np.random.seed()
np.random.rand(5)
# array([0.2279021 , 0.86468092, 0.09682891, 0.10720119, 0.01510727])