Numpy 矩阵运算
信息
2024年8月10日 · ·
NumPy(Numerical Python)是 Python 中用于科学计算的一个开源库,它提供了一个强大的多维数组对象以及各种操作这些数组的函数;NumPy 可以被认为是 Python 科学计算的基础库之一;
NumPy 的主要特点
-
多维数组对象
:NumPy 提供了 ndarray 类型,是一个 n 维数组对象,可以储存同类型元素的集合(例如整数、浮点数等),与 Python 的原生列表相比,ndarray 对象占用更少的内存,支持更快的运算; -
广播功能
:NumPy 支持在不同形状和大小的数组之间进行算术运算,这个功能称为广播;对于每个二进制 ufunc 操作(加减乘除等),它会尝试将两个输入向量转换成相同的形状并进行计算,使得您可以使用简单的代码来执行操作,而无需编写循环; -
转换功能
:NumPy 提供了丰富的数据类型来表示数字,字符串和其他变量类型;这些数据类型可以用于 Numpy 数组中,它们定义了每个元素的大小和解释方式;此外,NumPy 还提供了许多方便的功能来从其他 Python 数据结构中创建数组; -
数学函数库
:NumPy 内置了许多常见的数学函数,如三角函数、指数函数、对数函数等,还有一些高级数学函数,如线性代数、随机数生成器等; -
文件 I/O
:NumPy 支持从和到磁盘读写数据和文件;
NumPy 是 Python 科学计算的重要工具,被广泛地应用于各种领域,如数据分析、机器学习、图像处理等;
引入 numpy
>>> import numpy as np
1. 数组的初始化
1. 使用 list 初始化数组
# 调用 np.array 从 list 初始化一个数据
>>> l = [1, 2, 3]
>>> print(type(l))
>>> print(l)
<class 'list'>
[1, 2, 3]
>>> a = np.array([1, 2, 3])
>>> print(type(a))
>>> print(a)
<class 'numpy.ndarray'>
[1 2 3]
>>> a
array([1, 2, 3])
>>> a[2]
3
>>> a[0] = 5
>>> a
array([5, 2, 3])
# 二维数组
>>> b = np.array([[1, 2, 3], [2, 3, 4]])
>>> b
array([[1, 2, 3],
[2, 3, 4]])
>>> type(b)
numpy.ndarray
# 数组的维度
>>> b.shape
(2, 3)
>>> b[0, 2]
3
2. 内置构建数组的函数
初始化一个以 0 填充的数组
>>> a = np.zeros((2, 3))
>>> a
array([[0., 0., 0.],
[0., 0., 0.]])
初始化一个以 1 填充的数组
>>> b = np.ones((1, 2))
>>> b
array([[1., 1.]])
初始化一个以自定义数(比如 8 )填充的数组
>>> c = np.full((2, 2), 8)
>>> c
array([[8, 8],
[8, 8]])
对角矩阵
>>> d = np.eye(3, k=1)
>>> d
array([[0., 1., 0.],
[0., 0., 1.],
[0., 0., 0.]])
随机数矩阵
>>> e = np.random.random((3, 2))
>>> e
array([[0.61689958, 0.48564929],
[0.50384802, 0.89786453],
[0.08463754, 0.9107176 ]])
没有被初始化值的矩阵
>>> f = np.empty((2, 3, 4))
>>> f
array([[[3.10503618e+231, 3.10503618e+231, 1.03753786e-322,
0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000]],
[[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
2.28093341e+243],
[3.10503618e+231, 3.10503618e+231, 6.42285340e-323,
0.00000000e+000],
[0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000]]])
等差数列
>>> g = np.arange(15)
>>> g
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
>>> g.shape
(15,)
>>> g.dtype
dtype('int64')
3. 指定数据类型的数组
# 不指定则自动匹配
>>> int_arr = np.array([1, 2, 3, 4, 5])
>>> '%s %s' % (int_arr, int_arr.dtype)
'[1 2 3 4 5] int64'
>>> float_arr = np.array([1, 2, 3, 4, 5], dtype=np.float64)
>>> '%s %s' % (float_arr, float_arr.dtype)
'[1. 2. 3. 4. 5.] float64'
4. 使用 astype 复制数组并转换数据类型
>>> float_arr = int_arr.astype(np.float64)
>>> '%s %s' % (float_arr, float_arr.dtype)
'[1. 2. 3. 4. 5.] float64'
# astype 将 float 转 int 时,会丢掉小数部分
>>> float_arr = np.array([3.5, 2.3, 3.4, -2.3])
>>> int_arr = float_arr.astype(np.int64)
>>> '%s(%s) => %s(%s)' % (float_arr, float_arr.dtype, int_arr, int_arr.dtype)
'[ 3.5 2.3 3.4 -2.3](float64) => [ 3 2 3 -2](int64)'
# astype 将字符串转数组,失败则抛异常
>>> str_arr = np.array(['1.2', '2.4', '5.6', 'asdfa'], dtype=np.string_)
>>> str_arr
array([b'1.2', b'2.4', b'5.6', b'asdfa'], dtype='|S5')
# float_arr = str_arr.astype(dtype=np.float64)
# float_arr
# astype 使用其他数组的数据类型作为参数
>>> int_arr = np.arange(10)
>>> float_arr = np.array([2.3, 4.5, 6.5])
>>> int_arr.astype(dtype = float_arr.dtype)
array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
2. 数组的取值和赋值
>>> a = np.array([[1,2,3,4],[5,6,7,8],[9,10,12,11]])
>>> a
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 12, 11]])
1. 切片 - 对原数组对引用
# 多维数组从多个维度同时切片
>>> b = a[0:2, 2:4]
>>> b
array([[3, 4],
[7, 8]])
# 对切片出来的数组赋值, b 只是对a 切片区的引用,copy() 函数可以实现复制
>>> b[0, 0] = 9999
>>> b, a
(array([[9999, 4],
[ 7, 8]]),
array([[ 1, 2, 9999, 4],
[ 5, 6, 7, 8],
[ 9, 10, 12, 11]]))
# 取第一行,得到的是值
>>> row_1 = a[1, :]
>>> row_1, row_1.shape
(array([5, 6, 7, 8]), (4,))
# 切第一行,得到的是数组
>>> row_2 = a[1:2, :]
>>> row_2, row_2.shape
(array([[5, 6, 7, 8]]), (1, 4))
# [1] 与 1:2 效果一样
>>> row_3 = a[[0, 2], :]
>>> row_3, row_3.shape
(array([[ 1, 2, 9999, 4],
[ 9, 10, 12, 11]]),
(2, 4))
# 取第二个维度(列)的一列,结果还是行,只有一个维度
>>> col_1 = a[:, 1]
>>> col_1, col_1.shape
(array([ 2, 6, 10]), (3,))
# 对每一行的每一列切片
>>> col_2 = a[:, 1:2]
>>> col_2, col_2.shape
(array([[ 2],
[ 6],
[10]]),
(3, 1))
2. 通过下标 - 重建新数组
>>> a
array([[ 1, 2, 9999, 4],
[ 5, 6, 7, 8],
[ 9, 10, 12, 11]])
>>> b = a[[0, 1, 2, 2], [2, 1, 2, 3]]
>>> b, b.shape
(array([9999, 6, 12, 11]), (4,))
# 等同于这样:
>>> c = np.array([a[0, 2], a[1, 1], a[2, 2], a[2, 3]])
>>> c, c.shape
(array([9999, 6, 12, 11]), (4,))
# 取 (0, 0),(2, 1),(1, 2),(0, 3)
>>> i = np.array([0, 2, 1, 0])
>>> a[i, np.array(np.arange(4))]
array([ 1, 10, 7, 4])
# 对指定范围赋值
>>> a[i, np.array(np.arange(4))] += 10
>>> a
array([[ 11, 2, 9999, 14],
[ 5, 6, 17, 8],
[ 9, 20, 12, 11]])
3. 通过条件
>>> bool_index = a > 2
>>> bool_index, bool_index.shape
(array([[ True, False, True, True],
[ True, True, True, True],
[ True, True, True, True]]),
(3, 4))
>>> a[bool_index]
array([ 11, 9999, 14, 5, 6, 17, 8, 9, 20, 12, 11])