目录
1、numpy 介绍
numpy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象、各种派生对象(例如掩码数组和矩阵)以及用于对数组进行快速操作的各种方法,包括数学、逻辑、形状操作、排序、选择、I/O 、离散傅里叶变换、基本线性代数、基本统计运算、随机模拟等等。
2、ndarray
(1)ndarray的属性
|-------|-----------------|
| 属性 | 说明 |
| shape | 数组的形状 |
| ndim | 数组的维度 |
| size | 数组总元素个数 |
| dtype | 数组中元素的类型 |
| T | 转置:行变列,列变行。 |
使用:
创建数组
python
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr)
print('========================')
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)
# 输出====================
[1 2 3 4]
========================
[[1 2 3]
[4 5 6]]
shape 使用
python
print('数组arr的形状为:', arr.shape)
print('数组的arr2形状为:', arr2.shape)
# 输出==============
数组arr的形状为: (4,)
数组的arr2形状为: (2, 3)
说明:
(2, 3): 数组形状为 2行3列
size使用
python
print('数组arr元素的个数为:', arr.size)
print('数组arr2元素的个数为:', arr2.size)
# 输出================
数组arr元素的个数为: 4
数组arr2元素的个数为: 6
ndim使用
python
print('数组arr的维度为:', arr.ndim)
print('数组arr2的维度为:', arr2.ndim)
# 输出============
数组arr的维度为: 1
数组arr2的维度为: 2
dtype使用
python
arr3 = np.array([1, 2, 3, 4])
arr4 = np.array([1.0, 2.0, 3.0])
arr5 = np.array([1, 1.0, 'abc'])
print('数组arr3的元素类型:', arr3.dtype)
print('数组arr4的元素类型:', arr4.dtype)
print('数组arr5的元素类型:', arr5.dtype)
# 输出==============
数组arr3的元素类型: int64
数组arr4的元素类型: float64
数组arr5的元素类型: <U32 (Unicode 字符串,长度 32)
T使用
python
arr6 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr6)
print('=============')
arr7 = arr6.T
print(arr7)
# 输出==========
[[1 2 3]
[4 5 6]]
=============
[[1 4]
[2 5]
[3 6]]
(2)ndarray的创建
|-----------------|---------------------------------------------------|--------------------------------|
| 类型 | 方法 | 说明 |
| 基础构造 |||
| 从 Python 数据结构创建 | np.array() | 将列表/元组转换为 ndarray |
| 复制数组 | np.copy() | 创建独立副本(深拷贝)与原数组相同但不共享内存 |
| 预定义形状填充 |||
| 全0数组 | np.zeros() | 快速初始化全0数组 |
| 全1数组 | np.ones() | 快速初始化全1数组 |
| 未初始化数组 | np.empty() | 预分配内存(值随机) |
| 填充固定值 | np.full() | 用指定值填充数组 |
| | zeros_like() ones_like() empty_like() | 返回与给定数组具有相同形状和类型的新数组 |
| 基于数值范围生成 |||
| 等差序列 | np.arange() | 生成步长固定的序列(不含终点) |
| 等间隔序列 | np.linspace() | 生成指定数量的等间隔值(含终点) |
| 对数间隔序列 | np.logspace() | 生成对数间隔值(如 10^0, 10^1, 10^2) |
| 特殊矩阵生成 |||
| 单位矩阵 | np.eye() | 生成单位矩阵(对角线为1) |
| 对角矩阵 | np.diag() | 生成以指定值为对角线的矩阵 |
| 随机数组生成 |||
| 均匀分布随机数 | np.random.rand() | 生成 [0,1) 均匀分布的随机数 |
| 正态分布随机数 | np.random.randn() | 生成标准正态分布随机数(均值为0,方差为1) |
| 随机整数 | np.random.randint() | 生成指定范围内的随机整数 |
使用:
- 数据结构创建
python
import numpy as np
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr2 = np.array(arr)
print(arr2)
# 输出=============
[ 1 2 3 4 5 6 7 8 9 10]
- 复制数组
python
arr3 = np.copy(arr2)
print('将数组arr2复制为arr3:', arr3)
arr2[0] = 20
print('修改数组arr2的第一个元素为20:', arr2)
print('再次输出arr3:', arr3)
# 输出================
将数组arr2复制为arr3: [ 1 2 3 4 5 6 7 8 9 10]
修改数组arr2的第一个元素为20: [20 2 3 4 5 6 7 8 9 10]
再次输出arr3: [ 1 2 3 4 5 6 7 8 9 10]
- 全0数组使用
python
# 创建一个2行3列的全0数组
arr4 = np.zeros((2,3))
print('输出arr4:', arr4)
print('=====指定数据类型===========')
arr4 = np.zeros((2,3), dtype=np.int64)
print('输出arr4:', arr4)
# 输出=====================
输出arr4: [[0. 0. 0.]
[0. 0. 0.]]
=====指定数据类型===========
输出arr4: [[0 0 0]
[0 0 0]]
- 全1数组使用
python
# 创建一个3行3列的 全1数组
arr4 = np.ones((3,3))
print('输出arr4:', arr4)
print('=====指定数据类型===========')
arr4 = np.ones((3,3), dtype=np.int64)
print('输出arr4:', arr4)
# 输出========================
输出arr4: [[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
=====指定数据类型===========
输出arr4: [[1 1 1]
[1 1 1]
[1 1 1]]
- 未初始化数组使用
python
# 未初始化数组
arr5 = np.empty((2,3))
print('输出arr5:', arr5)
# 输出=====================
输出arr5: [[0. 0. 0.]
[0. 0. 0.]]
不推荐直接使用:需手动填充数据,否则可能引入不可预测的错误。
需要注意的是,np.empty 并不保证数组元素被初始化为 0,它只是分配内存空间,数组中的元素值是未初始化的,可能是内存中的任意值。
- 固定值数组
python
# 固定值数组
arr6 = np.full((3,3), 3)
print('输出arr6:', arr6)
# 输出======================
输出arr6: [[3 3 3]
[3 3 3]
[3 3 3]]
- 返回与给定数组具有相同形状和类型的新数组
python
arr7 = np.zeros_like(arr6)
print('输出arr7:', arr7)
arr8 = np.ones_like(arr6)
print('输出arr8:', arr8)
arr9 = np.empty_like(arr6)
print('输出arr9:', arr9)
arr10 = np.full_like(arr6, 10)
print('输出arr10:', arr10)
# 输出========================
输出arr7: [[0 0 0]
[0 0 0]
[0 0 0]]
输出arr8: [[1 1 1]
[1 1 1]
[1 1 1]]
输出arr9: [[1 1 1]
[1 1 1]
[1 1 1]]
输出arr10: [[10 10 10]
[10 10 10]
[10 10 10]]
- 等差序列数组
python
arr = np.arange(0, 10, 2)
print('等差数组:', arr)
# 输出=============
等差数组: [0 2 4 6 8]
- 等间隔序列数组
数组元素类型为浮点型
python
arr = np.linspace(0, 10, 5)
print('等间隔序列数组:', arr)
# 输出=================
等间隔序列数组: [ 0. 2.5 5. 7.5 10. ]
- 对数间隔数组
参数为:指数范围、元素个数
python
arr = np.logspace(0, 2, 3)
print('对数间隔数组:', arr)
# 输出=================
对数间隔数组: [ 1. 10. 100.]
- 单位矩阵
python
# 单位矩阵
arr = np.eye(3)
print('单位矩阵:')
print(arr)
arr = np.eye(3, 4, dtype=np.int64)
print('单位矩阵:')
print(arr)
# 输出===============
单位矩阵:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
单位矩阵:
[[1 0 0 0]
[0 1 0 0]
[0 0 1 0]]
- 对角矩阵
python
# 对角矩阵
arr = np.diag([1, 2, 3, 4])
print('对角矩阵: ')
print(arr)
# 输出==============
对角矩阵:
[[1 0 0 0]
[0 2 0 0]
[0 0 3 0]
[0 0 0 4]]
- 均匀分部随机数
用 [0, 1) 上均匀分布的随机样本填充
python
arr = np.random.rand(3)
print('均匀分部随机数:')
print(arr)
arr = np.random.rand(3,3)
print('均匀分部随机数:')
print(arr)
# 输出==============
均匀分部随机数:
[0.36473078 0.50934986 0.88033767]
均匀分部随机数:
[[0.16111821 0.28896626 0.16465106]
[0.01351598 0.4191022 0.08019565]
[0.51035863 0.87555856 0.17917408]]
- 正态分布随机数
用标准正态分布(均值为0,标准差为1)的随机样本填充,大部分分布在[-3, 3]之间
python
arr =np.random.randn(3, 3)
print('正态分布随机数:')
print(arr)
# 输出===================
正态分布随机数:
[[ 0.16275616 -0.21264772 0.78513191]
[ 0.50712782 0.14538494 2.63594323]
[ 0.63971575 1.9114478 -0.8866299 ]]
- 随机整数
python
arr = np.random.randint(0,10,(3,3))
print('给定范围的随机整数:')
print(arr)
# 输出===================
给定范围的随机整数:
[[3 2 8]
[3 6 0]
[9 2 5]]
-
随机浮点数
-
从低位(包含)到高位(不包含)上均匀分布的随机浮点数填充。
python
arr = np.random.uniform(0,10,(3,3))
print('随机浮点数:')
print(arr)
# 输出============
随机浮点数:
[[9.19338974 6.52402857 2.34806454]
[1.14384241 0.67074388 9.0034869 ]
[3.58190019 2.06654453 1.93736781]]
- 设置随机种子
python
np.random.seed(2)
arr = np.random.rand(3)
print('随机种子:')
print(arr)
# 输出=======每次输出的数据都是一样的
随机种子:
[0.4359949 0.02592623 0.54966248]
(3)ndarray的索引与切片
|-------------------------|---------------------------------|-------------------------------------|
| 类型 | 用法 | 描述 |
| 基本索引 | arr[行位置, 列位置] | 通过整数索引直接访问元素。索引从0开始。 |
| 行 / 列切片 | arr[ : , : ] | 使用冒号 : 切片语法选择行或列的子集。 |
| 连续切片 | arr[::, ::] | 从起始索引到结束索引按步长切片。 |
| 使用 slice 函数 | arr[slice()] | 通过 slice(start, stop, step) 定义切片规则。 |
| 布尔索引 | arr[(arr > X) & (arr < Y)] | 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。 |
- 基本索引使用
python
arr = np.arange(1, 10)
print(arr)
arr = arr.reshape(3, 3)
print(arr)
# 获取1行3列索引位置的值 索引是从0开始的
print('获取1行3列索引位置的值: ', arr[0, 2])
# 输出========================
[1 2 3 4 5 6 7 8 9]
[[1 2 3]
[4 5 6]
[7 8 9]]
获取1行3列索引位置的值: 3
- 切片的使用
python
print('第1行: ', arr[0, :])
print('所有行的第2列: ', arr[:, 1])
print('第1行之后的所有数据: ', arr[1:])
# 输出========================
第1行: [1 2 3]
所有行的第2列: [2 5 8]
第1行之后的所有数据: [[4 5 6]
[7 8 9]]
- 连续切片的使用
python
arr = np.arange(1, 100, 2)
# print(arr)
arr = arr.reshape(5, 10)
print(arr)
print('隔行隔列取样:')
print(arr[::2, ::2])
print('取1-4行之间隔行,1列之后隔列的数据:')
print(arr[1:4:2, 1::2])
# 输出=================
[[ 1 3 5 7 9 11 13 15 17 19]
[21 23 25 27 29 31 33 35 37 39]
[41 43 45 47 49 51 53 55 57 59]
[61 63 65 67 69 71 73 75 77 79]
[81 83 85 87 89 91 93 95 97 99]]
隔行隔列取样:
[[ 1 5 9 13 17]
[41 45 49 53 57]
[81 85 89 93 97]]
取1-4行之间隔行,1列之后隔列的数据:
[[23 27 31 35 39]
[63 67 71 75 79]]
- 使用slice()
python
print('原数组:',arr)
print('获取第二行数据:', arr[slice(1, 2, 2)])
print('获取第二行和第4行的第二列:',arr[slice(1, 4, 2), slice(1, 3, 2)])
# 输出====================
原数组: [[ 1 3 5 7 9 11 13 15 17 19]
[21 23 25 27 29 31 33 35 37 39]
[41 43 45 47 49 51 53 55 57 59]
[61 63 65 67 69 71 73 75 77 79]
[81 83 85 87 89 91 93 95 97 99]]
获取第二行数据: [[21 23 25 27 29 31 33 35 37 39]]
获取第二行和第4行的第二列: [[23]
[63]]
- 布尔索引
python
print('布尔筛选:', arr[(arr > 20) & (arr < 60)])
# 输出==========================
布尔筛选: [21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59]
总结:ndarray对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样。
可以通过内置的slice函数,或者冒号设置start, stop及step参数进行切片,从原数组中切割出一个新数组。
python
import numpy as np
arr = np.arange(10)
print(arr)
# [0 1 2 3 4 5 6 7 8 9
#获取索引为2的数据
print(arr[2])
# 2
# 从索引 2开始到索引9(不包含)停止,间隔为2
print(arr[slice(2,9,2)])
# [2 4 6 8]
# 从索引2开始到索引9(不包含)停止,间隔为2
print(arr[2:9:2])
# [2 4 6 8]
# 从索引2开始到最后(不包含),默认间隔为1
print(arr[2:])
# [2 3 4 5 6 7 8 9]
# 从索引2开始到索引9(不包含)结束,默认间隔为1
print(arr[2:9])
# [2 3 4 5 6 7 8]
切片语法规则 :start:stop:step,左闭右开区间(包含 start,不包含 stop)。
(4)ndarray的基本运算
- 相同大小数组间的运算
python
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
print('原数组:')
print(arr1)
print('------------------')
print(arr2)
# 加法
print('加法:')
print(arr1 + arr2)
# 减法
print('减法:')
print(arr1 - arr2)
# 乘法
print('乘法:')
print(arr1 * arr2)
# 除法
print('除法:')
print(arr1 / arr2)
# 输出===========================
原数组:
[[1 2 3]
[4 5 6]]
------------------
[[ 7 8 9]
[10 11 12]]
加法:
[[ 8 10 12]
[14 16 18]]
减法:
[[-6 -6 -6]
[-6 -6 -6]]
乘法:
[[ 7 16 27]
[40 55 72]]
除法:
[[0.14285714 0.25 0.33333333]
[0.4 0.45454545 0.5 ]]
- 数组与标量间的运算
python
# 加法
print('加法:')
print(arr1 + 3)
# 减法
print('减法:')
print(arr1 - 3)
# 乘法
print('乘法:')
print(arr1 * 3)
# 除法
print('除法:')
print(arr1 / 3)
# 输出==========================
加法:
[[4 5 6]
[7 8 9]]
减法:
[[-2 -1 0]
[ 1 2 3]]
乘法:
[[ 3 6 9]
[12 15 18]]
除法:
[[0.33333333 0.66666667 1. ]
[1.33333333 1.66666667 2. ]]
- 矢量化运算
要求参与运算的数组**形状完全相同**(否则会报错或触发广播机制)
python
# 矢量化运算
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
print('矢量化运算结果:', arr1 + arr2)
# 输出-----------------
矢量化运算结果: [5 7 9]
- 广播机制
- 允许不同形状的数组进行运算(如标量与数组、行向量与列向量等)。
- 如果俩个数组的维度数不相同,那么小维度数组的形状将会在最左边补1。
- 如果俩个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度大小(元素个数)为1的维度开始扩展 ,(维度必须是1开始)直到所有维度都一样, 以匹配另一个数组的形状。
- 如果俩个数组的形状在任何一个维度上都不匹配,并且没有任何一个维度大小等于1,那么会引发异常。
python
# 广播机制
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[5]])
print('广播机制: ', arr1 + arr2)
print('广播机制: ', arr1 * arr2)
print('=================')
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[5], [6]])
print('广播机制: ', arr1 + arr2)
print('广播机制: ', arr1 * arr2)
print('=================')
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[5], [6], [7]])
print('广播机制: ', arr1 + arr2)
print('广播机制: ', arr1 * arr2)
# 输出--------------------------------
广播机制: [[ 6 7 8]
[ 9 10 11]]
广播机制: [[ 5 10 15]
[20 25 30]]
=================
广播机制: [[ 6 7 8]
[10 11 12]]
广播机制: [[ 5 10 15]
[24 30 36]]
=================
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[14], line 20
17 arr1 = np.array([[1, 2, 3], [4, 5, 6]])
18 arr2 = np.array([[5], [6], [7]])
---> 20 print('广播机制: ', arr1 + arr2)
21 print('广播机制: ', arr1 * arr2)
ValueError: operands could not be broadcast together with shapes (2,3) (3,1)
- 矩阵乘法
使用np.dot()、ndarray.dot()、@可以进行矩阵乘法运算。
python
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[6, 5], [4, 3], [2, 1]])
print(np.dot(arr1, arr2))
print(arr1.dot(arr2))
print(arr1 @ arr2)
•结果矩阵第一行第一列的元素:
计算 arr1 的第一行 [1, 2, 3] 与 arr2 的第一列 [6, 4, 2] 对应元素乘积之和,即 1*6 + 2*4 + 3*2 = 6 + 8 + 6 = 20。
•结果矩阵第一行第二列的元素:
计算 arr1 的第一行 [1, 2, 3] 与 arr2 的第二列 [5, 3, 1] 对应元素乘积之和,即 1*5 + 2*3 + 3*1 = 5 + 6 + 3 = 14。
•结果矩阵第二行第一列的元素:
计算 arr1 的第二行 [4, 5, 6] 与 arr2 的第一列 [6, 4, 2] 对应元素乘积之和,即 4*6 + 5*4 + 6*2 = 24 + 20 + 12 = 56。
•结果矩阵第二行第二列的元素:
计算 arr1 的第二行 [4, 5, 6] 与 arr2 的第二列 [5, 3, 1] 对应元素乘积之和,即 4*5 + 5*3 + 6*1 = 20 + 15 + 6 = 41。
所以,手动计算得到的结果矩阵是 [[20, 14], [56, 41]]。
(5)ndarray 常用函数
- 基本函数
|-------------------|--------------------------------------------------------------|
| 函数 | 说明 |
| np.sqrt(x) | 计算平方根 |
| np.exp(x) | 计算指数(e^x) |
| np.log(x) | 计算自然对数(ln(x)) |
| np.sin(x) | 计算正弦值 |
| np.abs(x) | 计算绝对值 |
| np.power(a, b) | 计算 a 的 b 次幂 |
| np.round(x, n) | 四舍五入(保留 n 位小数) |
| np.ceil(x) | 向上取整(不小于原数的最小整数) |
| np.floor(x) | 向下取整(不大于原数的最大整数) |
| np.rint(x) | 四舍五入到最近的整数;当需要舍入的数字恰好是 5 时,会看 5 前面的数字,如果是偶数则直接舍去 5,如果是奇数则进位。 |
| np.multiply(a, b) | 元素级乘法(等价于 a * b) |
| np.divide(a, b) | 元素级除法(等价于 a / b) |
| np.isnan(x) | 检测 NaN 值 |
python
# 计算平方根
arr1 = np.array([4, 9, 10])
print('平方根: ', np.sqrt(arr1))
print('========================')
# 计算指数
arr1 = np.array([0, 1, 2])
print('计算指数: ', np.exp(arr1))
print('========================')
# 计算自然对数
arr1 = np.array([1, 2])
print('计算自然对数: ', np.log(arr1))
print('========================')
# 计算正弦值
print('计算正弦值: ', np.sin(np.pi/2))
print('========================')
# 计算绝对值
arr1 = np.array([1, 2, -1, -2])
print('计算绝对值: ', np.abs(arr1))
print('========================')
# 计算a的b次幂
print('计算a的b次幂: ', np.power(2, 3))
print('========================')
# 四舍五入,保留n位小数
print('四舍五入,保留n位小数: ', np.round(2.156, 2))
print('========================')
# 向上取整
arr1 = np.array([1.2, 2.5, -1.1, -2.6])
print('向上取整: ', np.ceil(arr1))
print('========================')
# 向下取整
arr1 = np.array([1.2, 2.5, -1.1, -2.6])
print('向下取整: ', np.floor(arr1))
print('========================')
# 四舍五入到最近的整数
arr1 = np.array([1.3, 1.5, 2.3, 2.5])
print('四舍五入到最近的整数: ', np.rint(arr1))
print('========================')
# 乘法
print('乘法: ', np.multiply(3, 5))
print('========================')
# 判断NAN
print('判断NAN: ', np.isnan([1, 0, np.nan, -1]))
print('========================')
# 输出-----------------------------
平方根: [2. 3. 3.16227766]
========================
计算指数: [1. 2.71828183 7.3890561 ]
========================
计算自然对数: [0. 0.69314718]
========================
计算正弦值: 1.0
========================
计算绝对值: [1 2 1 2]
========================
计算a的b次幂: 8
========================
四舍五入,保留n位小数: 2.16
========================
向上取整: [ 2. 3. -1. -2.]
========================
向下取整: [ 1. 2. -2. -3.]
========================
四舍五入到最近的整数: [1. 2. 2. 2.]
========================
乘法: 15
========================
判断NAN: [False False True False]
========================
- 统计函数
|-----------------------|------------------|
| 函数 | 说明 |
| np.sum(x) | 求和 |
| np.mean(x) | 计算均值 |
| np.median(x) | 计算中位数 |
| np.std(x) | 计算标准差 |
| np.var(x) | 计算方差 |
| np.min(x) / np.max(x) | 查找最小值/最大值 |
| np.percentile(x, q) | 计算分位数(q: 0~100) |
| np.argmax(x) | 返回最大值的索引 |
| np.argmin(x) | 返回最小值的索引 |
| np.cumsum(x) | 计算累积和(逐元素累加结果) |
| np.cumprod(x) | 计算累积积(逐元素累乘结果) |
使用场景
|-----------|----------------------------------------|----------------|----------------------|
| 统计量名称 | 数学定义与解释 | 常见用途 | 图示理解建议(文本) |
| 总和(和) | 所有数值相加的结果 | 总支出、总收入、总分等 | 直方图每列的"高度总和" |
| 计数(非空) | 所有非缺失值的数量 | 数据有效性统计 | 每列或每组的"存在数量" |
| 唯一计数 | 去重后的值的个数 | 用户量、种类、独特答案数等 | 彩色圆点图:每种颜色的数量 |
| 频率统计 | 每个唯一值出现的次数 | 投票结果、偏好选项统计 | 每种值为一柱的频数柱状图 |
| 平均数 | 所有数值的总和 / 个数 | 成绩均值、产品均价 | 数轴上"重心"位置 |
| 中位数 | 将所有值排序后位于中间位置的那个值 | 房价中位数、收入中位数 | 数轴上"居中"点 |
| 众数 | 出现频率最高的值;可能有多个 | 最常见类别、最流行选项 | 柱状图中"最高柱"的位置 |
| 众数个数 | 用于判断是否有多个众数 | 检查分布集中性 | 多个柱一样高 → 多众数 |
| 最大值 | 数据中的最大元素 | 最高温度、最大销量 | 数轴最右端的点 |
| 最小值 | 数据中的最小元素 | 最低成绩、最低价格 | 数轴最左端的点 |
| 分位数 | 把数据分成若干个相同大小的部分,第 q 个分位数是从小到大第 q 比例处的值 | 算工资等级、考试分数线 | 25%、50%、75%点→形成"箱型图" |
| 方差 | 所有数据与平均值之差的平方和的平均数(度量"离均差"的平方) | 波动性分析、风险评估 | 离平均数越远的点 → 贡献越大 |
| 标准差 | 方差的平方根;表示数据的波动程度 | 正态分布、偏差分析、误差建模 | 平均数±1个标准差 → 约68%数据范围 |
| 协方差 | 两个变量各自与均值之差乘积的平均值,衡量两者的变化趋势是否一致 | 股价、气温等变量共同趋势 | 趋势一致 → 正值,反向 → 负值 |
| 相关系数 | 标准化的协方差,范围为 [-1, 1],衡量两个变量之间的线性相关程度 | 预测模型、特征选择、相关分析 | 趋势完全相同 → 1,完全相反 → -1 |
python
# 求和
arr1 = np.array([1, 2, 3, 4])
print('求和: ', np.sum(arr1))
print('===========================')
# 平均值
print('平均值: ', np.mean(arr1))
print('===========================')
# 中位数
print('中位数: ', np.median(arr1))
print('===========================')
# 标准差
print('标准差: ', np.std(arr1))
print('===========================')
# 方差
print('方差: ', np.var(arr1))
print('===========================')
# 最小值
print('最小值: ', np.min(arr1))
print('===========================')
# 最大值
print('最大值: ', np.max(arr1))
print('===========================')
# 分位数
print('分位数: ', np.percentile(arr1, 10))
print('===========================')
# 最大值索引
print('最大值索引: ', np.argmax(arr1))
print('===========================')
# 最小值索引
print('最小值索引: ', np.argmin(arr1))
print('===========================')
# 计算累积和
print('计算累积和: ', np.cumsum(arr1))
print('===========================')
# 计算累积积
print('计算累积积: ', np.cumprod(arr1))
print('===========================')
# 输出--------------------------------------
求和: 10
===========================
平均值: 2.5
===========================
中位数: 2.5
===========================
标准差: 1.118033988749895
===========================
方差: 1.25
===========================
最小值: 1
===========================
最大值: 4
===========================
分位数: 1.3
===========================
最大值索引: 3
===========================
最小值索引: 0
===========================
计算累积和: [ 1 3 6 10]
===========================
计算累积积: [ 1 2 6 24]
===========================
- 比较函数
|---------------------------|----------------------------|
| 函数 | 功能说明 |
| np.greater(a, b) | 元素级比较 a > b |
| np.less(a, b) | 元素级比较 a < b |
| np.equal(a, b) | 元素级比较 a == b |
| np.logical_and(a, b) | 逻辑与(逐元素) |
| np.logical_or(a, b) | 逻辑或(逐元素) |
| np.logical_not(a) | 逻辑非(逐元素) |
| np.any(a) | 检查数组中是否 至少有一个元素 为 True |
| np.all(a) | 检查数组中是否 所有元素 为 True |
| np.where(condition, x, y) | 根据条件选择元素 |
python
arr1 = np.array([1, 3, 5])
arr2 = np.array([2, 2, 5])
# 判断a > b
print('判断a > b: ', np.greater(arr1, arr2))
print('===========================')
# 判断a < b
print('判断a < b: ', np.less(arr1, arr2))
print('===========================')
# 判断a = b
print('判断a = b: ', np.equal(arr1, arr2))
print('===========================')
arr3 = np.array([0, 1, 1, 0])
arr4 = np.array([0, 0, 1, 1])
# 逻辑与
print('逻辑与: ', np.logical_and(arr3, arr4))
print('===========================')
# 逻辑或
print('逻辑或: ', np.logical_or(arr3, arr4))
print('===========================')
# 逻辑非
print('逻辑非: ', np.logical_not(arr3))
print('===========================')
# 检查数组中是否 至少有一个元素 为 True
print('检查数组中是否 至少有一个元素 为 True: ', np.any([0, 0, 0, 1]))
print('===========================')
# 检查数组中是否 所有元素 为 True
print('检查数组中是否 所有元素 为 True: ', np.all([0, 0, 0, 1]))
print('===========================')
# 根据条件判断
arr5 = np.array([1, 2, 3, 4])
print('根据条件判断: ', np.where(arr5 > 3, arr5, 0))
print('===========================')
# 根据条件判断(嵌套)
arr6 = np.random.randint(50, 100, 10)
print('学生分数:', arr6)
print('根据条件判断: ', np.where(arr6 < 60,
'不及格', np.where(arr6 < 80, '良好','优秀')))
print('===========================')
# 根据条件判断select使用
print('根据条件判断: ', np.select([arr6 >= 80, (arr6 < 80) & (arr6 >= 60), arr6 < 60], ['优秀', '良好', '不及格'], default='未知'))
print('===========================')
# 输出------------------------------------------
判断a > b: [False True False]
===========================
判断a < b: [ True False False]
===========================
判断a = b: [False False True]
===========================
逻辑与: [False False True False]
===========================
逻辑或: [False True True True]
===========================
逻辑非: [ True False False True]
===========================
检查数组中是否 至少有一个元素 为 True: True
===========================
检查数组中是否 所有元素 为 True: False
===========================
根据条件判断: [0 0 0 4]
===========================
学生分数: [67 75 76 91 51 98 63 50 85 85]
根据条件判断: ['良好' '良好' '良好' '优秀' '不及格' '优秀' '良好' '不及格' '优秀' '优秀']
===========================
根据条件判断: ['良好' '良好' '良好' '优秀' '不及格' '优秀' '良好' '不及格' '优秀' '优秀']
===========================
- 排序函数
|------------------|---------------|
| 函数 | 功能说明 |
| np.sort(x) | 返回排序后的副本 |
| x.sort() | 原地排序(修改原数组) |
| np.argsort(x) | 返回排序后的索引 |
| np.lexsort(keys) | 多键排序(按最后一列优先) |
python
np.random.seed(0)
arr7 = np.random.randint(1, 100, 20)
print('原始数组:', arr7)
# 排序函数 改变原数组
arr7.sort()
print('排序后数组:', arr7)
print('----------------------------------------------')
np.random.seed(0)
arr8 = np.random.randint(1, 100, 20)
print('原始数组:', arr8)
# 排序函数 不改变原数组
print('排序后数组:', np.sort(arr8))
print('原始数组:', arr8)
print('----------------------------------------------')
# 返回排序后的索引
print('返回排序后的索引:', np.argsort(arr8))
print('----------------------------------------------')
# 输出-----------------------------------
原始数组: [45 48 65 68 68 10 84 22 37 88 71 89 89 13 59 66 40 88 47 89]
排序后数组: [10 13 22 37 40 45 47 48 59 65 66 68 68 71 84 88 88 89 89 89]
----------------------------------------------
原始数组: [45 48 65 68 68 10 84 22 37 88 71 89 89 13 59 66 40 88 47 89]
排序后数组: [10 13 22 37 40 45 47 48 59 65 66 68 68 71 84 88 88 89 89 89]
原始数组: [45 48 65 68 68 10 84 22 37 88 71 89 89 13 59 66 40 88 47 89]
----------------------------------------------
返回排序后的索引: [ 5 13 7 8 16 0 18 1 14 2 15 3 4 10 6 17 9 11 12 19]
- 去重函数
|---------------|-------------------|
| 函数 | 功能说明 |
| np.unique(x) | 返回唯一值并排序 |
| np.in1d(a, b) | 检查 a 的元素是否在 b 中存在 |
python
np.random.seed(0)
arr9 = np.random.randint(1, 100, 20)
print('原始数组:', arr9)
# 返回唯一值并排序
print('函数去重:', np.unique(arr9))
# 输出-----------------------------------
原始数组: [45 48 65 68 68 10 84 22 37 88 71 89 89 13 59 66 40 88 47 89]
函数去重: [10 13 22 37 40 45 47 48 59 65 66 68 71 84 88 89]
- 其他函数
|------------------------|----------|
| 函数 | 功能说明 |
| np.concatenate((a, b)) | 数组拼接 |
| np.split(x, indices) | 分割数组 |
| np.reshape(x, shape) | 调整数组形状 |
| np.copy(x) | 创建数组的深拷贝 |
| np.isnan(x) | 检测 NaN 值 |
python
# 数组拼接
arr10 = np.array([1, 2, 3])
arr11 = np.array([4, 5, 6])
print('拼接后数组:', np.concatenate((arr10, arr11)))
np.random.seed(0)
arr12 = np.random.randint(1, 100, 20)
print('原数组:', arr12)
# 分割数组
print('分割数组', np.split(arr12, 4))
print('分割数组', np.split(arr12, [6, 12, 18]))
# 调整数组形状
print('调整数组形状', np.reshape(arr12, (4, 5)))
# 输出----------------------------------------
拼接后数组: [1 2 3 4 5 6]
原数组: [45 48 65 68 68 10 84 22 37 88 71 89 89 13 59 66 40 88 47 89]
分割数组 [array([45, 48, 65, 68, 68], dtype=int32), array([10, 84, 22, 37, 88], dtype=int32), array([71, 89, 89, 13, 59], dtype=int32), array([66, 40, 88, 47, 89], dtype=int32)]
分割数组 [array([45, 48, 65, 68, 68, 10], dtype=int32), array([84, 22, 37, 88, 71, 89], dtype=int32), array([89, 13, 59, 66, 40, 88], dtype=int32), array([47, 89], dtype=int32)]
调整数组形状 [[45 48 65 68 68]
[10 84 22 37 88]
[71 89 89 13 59]
[66 40 88 47 89]]
3、综合练习
(1)温度数据分析
某城市一周的最高气温(℃)为 [28, 30, 29, 31, 32, 30, 29]。
- 计算平均气温、最高气温和最低气温。
- 找出气温超过 30℃ 的天数。
python
arr = np.array([28, 30, 29, 31, 32, 30, 29])
# 计算平均气温、最高气温和最低气温
print('平均气温: ', np.mean(arr))
print('最高气温: ', np.max(arr))
print('最低气温: ', np.min(arr))
print('---------------------------')
# 找出气温超过 30℃ 的天数
print('气温超过 30℃ 的天数: ', arr[arr > 30].size)
# 输出---------------------------------
平均气温: 29.857142857142858
最高气温: 32
最低气温: 28
---------------------------
气温超过 30℃ 的天数: 2
(2)学生成绩统计
某班级 5 名学生的数学成绩为 [85, 90, 78, 92, 88]。
- 计算成绩的平均分、中位数和标准差。
- 将成绩转换为百分制(假设满分为 100)。
python
arr = np.array([85, 90, 78, 92, 88])
# 计算成绩的平均分、中位数和标准差。
print('平均分: ', np.mean(arr))
print('中位数: ', np.median(arr))
print('标准差: ', np.std(arr))
# 输出--------------------------------
平均分: 86.6
中位数: 88.0
标准差: 4.882622246293481
(3)矩阵运算
给定矩阵 A = [[1, 2], [3, 4]] 和 B = [[5, 6], [7, 8]]。
- 计算 A + B 和 A * B(逐元素乘法)。
- 计算 A 和 B 的矩阵乘法(点积)。
python
arr1 = np.array([[1, 2], [3, 4]])
arr2 = np.array([[5, 6], [7, 8]])
# 计算A + B和A * B(逐元素乘法)。
print('A + B: ', arr1 + arr2)
print('A * B: ', arr1 * arr2)
print('---------------------')
# 计算A和B的矩阵乘法(点积)
print('A @ B: ', arr1 @ arr2)
print('点积: ', np.dot(arr1, arr2))
# 输出----------------------------------
A + B: [[ 6 8]
[10 12]]
A * B: [[ 5 12]
[21 32]]
---------------------
A @ B: [[19 22]
[43 50]]
点积: [[19 22]
[43 50]]
(4)随机数据生成
生成一个 (3, 4) 的随机整数数组,范围 [0, 10)。
- 计算每列的最大值和每行的最小值。
- 将数组中的所有奇数替换为 -1。
python
np.random.seed(0)
arr = np.random.randint(0, 10, (3, 4))
print('原始数组:', arr)
# 计算每列的最大值和每行的最小值
print('每列的最大值', np.max(arr, axis=0))
print('每行的最小值', np.min(arr, axis=1))
# 将数组中的所有奇数替换为 -1。
arr[arr % 2 == 1] = 0
print('所有奇数替换为 -1: ', arr)
# 输出-----------------------------------
原始数组: [[5 0 3 3]
[7 9 3 5]
[2 4 7 6]]
每列的最大值 [7 9 7 6]
每行的最小值 [0 3 2]
所有奇数替换为 -1: [[0 0 0 0]
[0 0 0 0]
[2 4 0 6]]
(5)数组变形
创建一个 1 到 12 的一维数组,并转换为 (3, 4) 的二维数组。
- 计算每行的和与每列的平均值。
- 将数组展平为一维数组。
python
arr = np.arange(1, 13).reshape(3,4)
print('原始数组:', arr)
# 计算每行的和与每列的平均值
print('每行的和: ', np.sum(arr, axis=1))
print('每列的平均值: ', np.mean(arr, axis=0))
# 将数组展平为一维数组
print('展平为一维数组: ', arr.flatten())
# 输出------------------------------------------
原始数组: [[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
每行的和: [10 26 42]
每列的平均值: [5. 6. 7. 8.]
展平为一维数组: [ 1 2 3 4 5 6 7 8 9 10 11 12]
(6)布尔索引
生成一个 (5, 5) 的随机数组,范围 [0, 20)。
- 找出数组中大于 10 的元素。
- 将所有大于 10 的元素替换为 0。
python
arr = np.random.randint(0,20, (5, 5))
print('原始数组:', arr)
# 找出数组中大于10的元素。
print('数组中大于10的元素: ', arr[arr > 10])
# 将所有大于10的元素替换为0。
arr[arr > 10] = 0
print('大于10的元素替换为0: ', arr)
# 输出----------------------------------------
原始数组: [[ 6 11 14 18 0]
[14 3 12 10 11]
[ 4 6 4 15 3]
[12 4 8 14 15]
[ 3 15 13 16 17]]
数组中大于10的元素: [11 14 18 14 12 11 15 12 14 15 15 13 16 17]
大于10的元素替换为0: [[ 6 0 0 0 0]
[ 0 3 0 10 0]
[ 4 6 4 0 3]
[ 0 4 8 0 0]
[ 3 0 0 0 0]]
(7)统计函数应用
某公司 6 个月的销售额(万元)为 [120, 135, 110, 125, 130, 140]。
- 计算销售额的总和、均值和方差。
- 找出销售额最高的月份和最低的月份。
python
arr = np.array([120, 135, 110, 125, 130, 140])
# 计算销售额的总和、均值和方差
print('总和: ', np.sum(arr))
print('均值: ', np.mean(arr))
print('方差: ', np.var(arr))
# 找出销售额最高的月份和最低的月份。
print('销售额最高的月份: ', np.argmax(arr))
print('销售额最低的月份: ', np.argmin(arr))
# 输出-------------------------------------
总和: 760
均值: 126.66666666666667
方差: 97.22222222222223
销售额最高的月份: 5
销售额最低的月份: 2
(8)数组拼接
给定 A = [1, 2, 3] 和 B = [4, 5, 6]。
- 水平拼接为 [1, 2, 3, 4, 5, 6]。
- 垂直拼接为 [[1, 2, 3], [4, 5, 6]]。
python
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 水平拼接为[1, 2, 3, 4, 5, 6]
print('水平拼接: ', np.concatenate((arr1, arr2), axis=0))
# 垂直拼接为[[1, 2, 3], [4, 5, 6]]。
print('垂直拼接: ', np.vstack((arr1, arr2)))
# 输出--------------------------
水平拼接: [1 2 3 4 5 6]
垂直拼接: [[1 2 3]
[4 5 6]]
(9)唯一值与排序
给定数组 [2, 1, 2, 3, 1, 4, 3]。
- 找出唯一值并排序。
- 计算每个唯一值出现的次数。
python
arr = np.array([2, 1, 2, 3, 1, 4, 3])
# 找出唯一值并排序
print('唯一值并排序: ', np.unique(arr))
# 计算每个唯一值出现的次数
unique_values, counts = np.unique(arr, return_counts=True)
print('唯一值出现的次数: ', counts)
# 输出--------------------------------
唯一值并排序: [1 2 3 4]
唯一值出现的次数: [2 2 2 1]
(10)缺失值处理
给定数组 [1, np.nan, 3, np.nan, 5]。
- 计算非缺失值的数量。
- 将缺失值替换为 0。
python
arr = np.array([1, np.nan, 3, np.nan, 5])
# 计算非缺失值的数量
print("非缺失值数量:", np.sum(~np.isnan(arr)))
arr[np.isnan(arr)] = 0
print('替换后: ', arr)
# 输出----------------------------------------
非缺失值数量: 3
替换后: [1. 0. 3. 0. 5.]