4 、Numpy
-
numpy介绍【了解】
- 一个开源的Python科学计算库
- 计算起来要比python简洁高效
- Numpy使用ndarray对象来处理多维数组
-
ndarray介绍
- NumPy提供了一个N维数组类型ndarray,它描述了相同类型的“items”的集合。
- 生成numpy对象:np.array()
-
ndarray的优势【掌握】
- 内存块风格
- list – 分离式存储,存储内容多样化
- ndarray – 一体式存储,存储类型必须一样
- ndarray支持并行化运算(向量化运算)
- ndarray底层是用C语言写的,效率更高,释放了GIL
- 内存块风格
-
N维数组-ndarray
- ndarray的属性
- ndarray.shape:数组维度的元组
- ndarray.ndim:数组维数
- ndarray.size:数组中的元素数量
- ndarray.itemsize:一个数组元素的长度(字节)
- ndarray.dtype:数组元素的类型
- ndarray的形状
- a.shape (2, 3) # 二维数组
- b = np.array([1,2,3,4]) (4,) # 一维数组
- c = np.array([[[1,2,3],[4,5,6]],[[1,2,3],[4,5,6]]]) (2, 2, 3) # 三维数组
- ndarray的类型
- type(score.dtype)
- a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
- a.dtype #dtype(‘float32’)
- ndarray的属性
-
基本操作
-
生成数组的方法
- 1、 生成0和1的数组
- np.ones(shape, dtype)
- np.ones_like(a, dtype)
- np.zeros(shape, dtype)
- np.zeros_like(a, dtype)
ones = np.ones([4,8]) ones np.zeros_like(ones)
- 2、从现有数组生成
- np.array(object, dtype) 深拷贝
- np.asarray(a, dtype) 浅拷贝
a2 = np.asarray(a)a = np.array([[1,2,3],[4,5,6]]) # 从现有的数组当中创建 a1 = np.array(a) # 相当于索引的形式,并没有真正的创建一个新的
- 3、生成固定范围的数组
- 创建等差数组 — 指定数量
- np.linspace (start, stop, num, endpoint)
- start:序列的起始值
- stop:序列的终止值
- num:要生成的等间隔样例数量,默认为50
- endpoint:序列中是否包含stop值,默认为ture
# 生成等间隔的数组 np.linspace(0, 100, 11) array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.])
- 创建等差数组 — 指定步长
- np.arange(start,stop, step, dtype)
- step:步长,默认值为1
np.arange(10, 50, 2)
- 创建等比数列
- np.logspace(start,stop, num)
- num:要生成的等比数列数量,默认为50
# 生成10^x np.logspace(0, 2, 3) array([ 1., 10., 100.])
- 4、生成随机数组
- 1、 生成0和1的数组
-
数组的索引、切片
- 直接进行索引,切片
- 对象[:, :] – 先行后列
-
形状修改
- ndarray.reshape(shape, order)
- 返回一个具有相同数据域,但shape不一样的视图
- 行、列不进行互换
# 在转换形状的时候,一定要注意数组的元素匹配 stock_change.reshape([5, 4]) stock_change.reshape([-1,10]) # 数组的形状被修改为: (2, 10), -1: 表示通过待计算
- ndarray.resize(new_shape)
- 修改数组本身的形状
- 行、列不进行互换
stock_change.resize([5, 4]) # 查看修改后结果 stock_change.shape (5, 4)
- ndarray.T
- 数组的转置
- 将数组的行、列进行互换
stock_change.T.shape (4, 5)
- ndarray.reshape(shape, order)
-
类型修改
- ndarray.astype(type)
- 返回修改了类型之后的数组
stock_change.astype(np.int32)
- ndarray.tostring([order])或者ndarray.tobytes([order])
- 构造包含数组中原始数据字节的Python字节
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[12, 3, 34], [5, 6, 7]]]) arr.tostring()
- ndarray.astype(type)
-
数组的去重
- np.unique()
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]]) >>> np.unique(temp) array([1, 2, 3, 4, 5, 6])
-
ndarray运算
- 逻辑运算
# 生成10名同学,5门功课的数据
>>> score = np.random.randint(40, 100, (10, 5))
# 取出最后4名同学的成绩,用于逻辑判断
>>> test_score = score[6:, 0:5]
# 逻辑判断, 如果成绩大于60就标记为True 否则为False
>>> test_score > 60
array([[ True, True, True, False, True],
[ True, True, True, False, True],
[ True, True, False, False, True],
[False, True, True, True, True]])
# BOOL赋值, 将满足条件的设置为指定的值-布尔索引
>>> test_score[test_score > 60] = 1
>>> test_score
array([[ 1, 1, 1, 52, 1],
[ 1, 1, 1, 59, 1],
[ 1, 1, 44, 44, 1],
[59, 1, 1, 1, 1]])
- 通用运算
np.all()
# 判断前两名同学的成绩[0:2, :]是否全及格
>>> np.all(score[0:2, :] > 60)
False
np.any()
# 判断前两名同学的成绩[0:2, :]是否有大于90分的
>>> np.any(score[0:2, :] > 80)
True
- np.where(三元运算符)
- np.where()
# 判断前四名学生,前四门课程中,成绩中大于60的置为1,否则为0
temp = score[:4, :4]
np.where(temp > 60, 1, 0)
* 复合逻辑需要结合np.logical_and和np.logical_or使用
# 判断前四名学生,前四门课程中,成绩中大于60且小于90的换为1,否则为0
np.where(np.logical_and(temp > 60, temp < 90), 1, 0)
# 判断前四名学生,前四门课程中,成绩中大于90或小于60的换为1,否则为0
np.where(np.logical_or(temp > 90, temp < 60), 1, 0)
- 统计运算
- 统计指标:
- np.max()
- np.min()
- np.median()
- np.mean()
- np.std()
- np.var()
- np.argmax(axis=) — 最大元素对应的下标
- np.argmin(axis=) — 最小元素对应的下标
- 统计指标:
# 接下来对于前四名学生,进行一些统计运算
# 指定列 去统计
temp = score[:4, 0:5]
print("前四名学生,各科成绩的最大分:{}".format(np.max(temp, axis=0)))
print("前四名学生,各科成绩的最小分:{}".format(np.min(temp, axis=0)))
print("前四名学生,各科成绩波动情况:{}".format(np.std(temp, axis=0)))
print("前四名学生,各科成绩的平均分:{}".format(np.mean(temp, axis=0)))
print("前四名学生,各科成绩最高分对应的学生下标:{}".format(np.argmax(temp, axis=0)))
5、数组间的运算
- 数组与数之间的运算
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
arr + 1
arr / 2
# 可以对比python列表的运算,看出区别
a = [1, 2, 3, 4, 5]
a * 3
- 数组与数组之间的运算
- 广播机制
- 数组的某一维度等长。
- 其中一个数组的某一维度为1 。
arr1 = np.array([[0],[1],[2],[3]])
arr1.shape
# (4, 1)
arr2 = np.array([1,2,3])
arr2.shape
# (3,)
arr1+arr2
# 结果是:
array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6]])
- 数据:矩阵
- 矩阵和向量
- 矩阵就是特殊的二维数组
- 向量就是一行或者一列的数据
- 矩阵加法和标量乘法
- 矩阵的加法:行列数相等的可以加。
- 矩阵的乘法:每个元素都要乘。
- 矩阵和矩阵(向量)相乘
- (M行, N列)*(N行, L列) = (M行, L列)
- 矩阵性质
- 矩阵不满足交换率,满足结合律
- 单位矩阵
- 对角线都是1的矩阵,其他位置都为0
- 矩阵运算
- np.matmul
- np.dot
>>> a = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
>>> b = np.array([[0.7], [0.3]])
>>> np.matmul(a, b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
>>> np.dot(a,b)
array([[81.8],
[81.4],
[82.9],
[90. ],
[84.8],
[84.4],
[78.6],
[92.6]])
注意:np.matmul和np.dot的区别
二者都是矩阵乘法。 np.matmul中禁止矩阵与标量的乘法。 在矢量乘矢量的內积运算中,np.matmul与np.dot没有区别。