Numpy
1、了解numpy数组的优点,掌握numpy数组的创建方法。
2、掌握numpy数组的基本性质。
3、掌握numpy的向量化操作。
4、掌握numpy的矩阵操作。
5、掌握numpy的广播操作。
6、掌握常见numpy通用函数。
7、掌握numpy高效、简洁的掩码操作。
Python原生的for循环是一种低效的循环,实现相同计算,Numpy的运行速度是Python循环的25倍,产生了质的飞跃
Numpy为什么如此高效:
Numpy是由C语言编写的
- 1、编译型语言VS解释性语言:C语言执行时,对代码进行整体编译,速度更快
- 2、连续单一类型存储VS分散多变类型存储:
- Numpy数组内的数据类型必须是统一的,如全部是浮点型,而Python列表支持任意类型数据的填充
- Numpy数组内的数据连续存储在内存中,而Python列表的数据分散在内存中
这种存储结构,与一些更加高效的底层处理方式更加的锲合
- 3、多线程VS线程锁:Python语言执行时有线程锁,无法真正的多线程并行,而C语言可以
在数据处理的过程中,遇到使用"Python for循环"实现一些向量化、矩阵化
操作的时候,要优先考虑用Numpy
Numpy数组的创建
列表创建
import numpy as np
# 创建列表
x = np.array([1, 2, 3, 4, 5])
print(x)
print(type(x))
print(type(x[0]))
print(x.shape)
"""
[1 2 3 4 5]
<class 'numpy.ndarray'>
<class 'numpy.int64'>
(5,)
"""
## 设置数组的数据类型
y = np.array([1, 2, 3, 4, 5], dtype="float32")
print(y)
print(type(y[0]))
"""
[1. 2. 3. 4. 5.]
<class 'numpy.float32'>
"""
## 二维数组
z = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(z)
print(z.shape)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
(3, 3)
"""
从头创建数组
import numpy as np
np.zeros(5, dtype=int) # 创建长度为5,值全为0的数组
np.ones((2, 4), dtype=float) # 创建一个2*4的浮点型数组,值都为1
np.full((3, 5), 8.8) # 创建一个3*5的数组,值都为8.8
np.eye(3) # 创建一个3*3的单位矩阵
np.arange(1, 15, 2) # 创建一个线性序列数组,从1开始,到15结束,步长为2
np.linspace(0, 1, 4) # 创建一个4个元素的数组,这四个数均匀的分配0-1
np.logspace(0, 9, 10) # 创建一个10个元素的数组,形成1~10^9的等比数列
np.random.random((3, 3)) # 创建一个3*3的,在0-1之间均匀分布的随机数构成的数组
np.random.normal(0, 1, (3, 3)) # 创建一个3*3的,均值为0,标准差为1的随机数构成的数组
np.random.randint(0, 10, (3, 3)) # 创建一个3*3的,在[0,10]之间随机整数构成的数组
# 随机重排列
x = np.array([10, 20, 30, 40])
np.random.permutation(x) # 生成新列表
np.random.shuffle(x) # 修改原列表
随机采样
import numpy as np
# 按指定形状采样
x = np.arange(10, 25, dtype=float)
print(x)
"""
[10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.]
"""
print(np.random.choice(x, size=(4, 3)))
"""
[[12. 23. 18.]
[11. 17. 18.]
[16. 11. 11.]
[12. 11. 20.]]
"""
# 按概率采样
print(np.random.choice(x, size=(4, 3), p=x/np.sum(x)))
"""
[[11. 20. 18.]
[14. 16. 20.]
[20. 20. 12.]
[21. 23. 23.]]
"""
Numpy数组的性质
数组的属性
import numpy as np
x = np.random.randint(10, size=(3, 4))
print(x)
# 数组的形状
print(x.shape)
# 数组的维度ndim
print(x.ndim)
# 数组的大小size
print(x.size)
# 数组的数据类型
print(x.dtype)
"""
[[7 4 1 7]
[4 6 4 1]
[4 1 2 2]]
(3, 4)
2
12
int64
"""
数组索引
import numpy as np
# 一维数组的索引
x1 = np.arange(10)
print(x1)
print(x1[0])
print(x1[-1])
"""
[0 1 2 3 4 5 6 7 8 9]
0
9
"""
# 二位数组的索引
x2 = np.random.randint(0, 20, (2, 3))
print(x2)
print(x2[0, 0]) # x2[0][0]
"""
[[17 13 0]
[16 7 16]]
17
"""
x2[1, 2] = 1.618
print(x2)
"""
[[15 1 9]
[ 1 17 1]]
"""
注意:numpy数组的数据类型是固定的,向一个整型数组插入一个浮点值,浮点值会向下进行取整
数组的切片
- 1、一维数组——跟列表一样
import numpy as np
x1 = np.arange(10)
print(x1)
print(x1[:3])
print(x1[3:])
print(x1[::-1])
"""
[0 1 2 3 4 5 6 7 8 9]
[0 1 2]
[3 4 5 6 7 8 9]
[9 8 7 6 5 4 3 2 1 0]
"""
- 2、多维数组——以二维为例
import numpy as np
x2 = np.random.randint(20, size=(3, 4))
print(x2)
print(x2[:2, :3]) # 前两行,前三列
print(x2[:2, 0:3:2]) # 前两行,前三列(每隔一列)
print(x2[::-1, ::-1])
"""
[[14 8 5 11]
[17 0 18 10]
[ 0 17 12 6]]
[[14 8 5]
[17 0 18]]
[[14 5]
[17 18]]
[[ 6 12 17 0]
[10 18 0 17]
[11 5 8 14]]
"""
- 3、获取数组的行和列
import numpy as np
x3 = np.random.randint(20, size=(3, 4))
print(x3)
print(x3[1, :]) # 第一行
print(x3[1])
print(x3[:, 2]) # 第2列
"""
[[10 2 2 1]
[ 8 16 16 5]
[19 4 15 10]]
[ 8 16 16 5]
[ 8 16 16 5]
[ 2 16 15]
"""
- 4、切片获取的是视图,而非副本
注意:视图元素发生修改,则原数组也相应发生修改
修改切片的安全方式:copy
x = x1[:2, :2].copy()
数组的变形——reshape
注意:reshape返回的是视图,而非副本
import numpy as np
x5 = np.random.randint(0, 10, (12,))
print(x5) # [8 6 4 7 0 7 5 3 4 4 9 0]
# 一维向量转行向量
x7 = x5.reshape(1, x5.shape[0]) # 等价于x5[np.newaxis, :]
print(x7) # [[6 6 0 9 6 7 1 7 1 1 7 2]]
# 一维向量转列向量
x7 = x5.reshape(x5.shape[0], 1) # 等价于x5[:, np.newaxis]
print(x7)
"""
[[4]
[3]
[4]
[8]
[5]
[7]
[8]
[8]
[5]
[5]
[7]
[4]]
"""
- 多维向量转一维向量:
- flatten返回的是副本
- ravel返回的是视图
- x6.reshape(-1)返回的是视图
import numpy as np
x6 = np.random.randint(0, 10, (3, 4))
print(x6)
x9 = x6.flatten()
print(x9)
"""
[[9 1 9 3]
[7 6 7 1]
[6 8 2 6]]
[9 1 9 3 7 6 7 1 6 8 2 6]
"""
数组的拼接
- 1、水平拼接——非视图
import numpy as np
x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[0, 1, 2]])
x3 = np.hstack([x1, x2])
print(x3)
"""
[[1 2 3 7 8 9]
[4 5 6 0 1 2]]
"""
x4 = np.c_[x1, x2]
print(x4)
"""
[[1 2 3 7 8 9]
[4 5 6 0 1 2]]
"""
- 2、垂直拼接——非视图
import numpy as np
x1 = np.array([[1, 2, 3],
[4, 5, 6]])
x2 = np.array([[7, 8, 9],
[0, 1, 2]])
x5 = np.vstack([x1, x2])
x6 = np.r_[x1, x2]
print(x5)
"""
[[1 2 3]
[4 5 6]
[7 8 9]
[0 1 2]]
"""
数组的分裂
- split的用法
import numpy as np
x6 = np.arange(10)
print(x6)
x1, x2, x3 = np.split(x6, [2, 7])
print(x1, x2, x3)
"""
[0 1 2 3 4 5 6 7 8 9]
[0 1] [2 3 4 5 6] [7 8 9]
"""
- hsplit的用法:分割列
- vsplit的用法:分割行
Numpy的四大运算
向量化运算
- 1、与数字的整体加减乘除等
import numpy as np
x = np.arange(10)
print(x)
print("-x", -x) # 相反数
print("x**2", x**2) # 平方
print("x//2", x//2) # 求整数商
print("x%2", x % 2) # 取余
"""
[0 1 2 3 4 5 6 7 8 9]
-x [ 0 -1 -2 -3 -4 -5 -6 -7 -8 -9]
x**2 [ 0 1 4 9 16 25 36 49 64 81]
x//2 [0 0 1 1 2 2 3 3 4 4]
x%2 [0 1 0 1 0 1 0 1 0 1]
"""
- 两个数组的运算:对应数组相应位置进行运算
## 广播运算
> 如果两个数组的形状在维度上不匹配,那么数组的形式会沿着维度为1的维度进行扩展以匹配另一个数组的形状
## 比较运算和掩码
## 花哨的索引
## 其他Numpy通用函数
- 数值排序:①np.sort(x)——产生临时副本,对x没有影响 ②x.sort()——替换原数组
- 获得排序索引: np.argsort(x)——相较于原数组
- 最大值、最小值:np.max(x) np.min(x)
- 数值求和、求积:np.sum(x)
- 按行求和: np.sum(x, axis=1)
- 按列求和: np.sum(x, axis=0)
- 求积: np.prod(x) x.prod()
### 中位数、均值、方差、标准差
- 中位数:np.median(x)
- 均值:np.mean(x)
- 方差:np.var(x)
- 标准差:np.std(x)
- 2、绝对值、三角函数、指数、对数
努力做最期待的自己。