一. 广播(Broadcast)
-
NumPy 的广播机制是一个强大的功能,使得不同形状的数组之间进行运算变得更加便利。通过广播,较小的数组将自动扩展以适应较大的数组,而无需显式地复制数据。
-
NumPy 的广播机制简化了数组间的操作,使得可以更灵活地进行数学计算。
广播的基本规则
- 维度匹配: 从后往前对齐两个数组的维度。如果某个维度的大小不同,NumPy 会尝试应用广播规则。
- 维度为1的扩展: 如果其中一个数组在某个维度上只有1(或者该维度不存在),则可以将其视为该维度上进行扩展。
- 相同的大小: 如果两个数组在某个维度上的大小相同,则可以直接进行计算。
- 若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
示例
import numpy as np
# 创建一个一维数组
a = np.array([1, 2, 3]) #1行3列
# 创建一个二维数组
b = np.array([[10], [20], [30]]) #3行1列
# 广播操作
c = a + b
print(c)
输出:
[[11 12 13]
[21 22 23]
[31 32 33]]
分析
在上面的代码中:
a
是一个形状为(3,)
的一维数组,b
是一个形状为(3, 1)
的二维数组。- 在进行
a + b
操作时,NumPy 将一维数组a
视作(1, 3)
的形状并进行广播,使其能够与b
进行计算。
注意事项
- 内存效率: 广播操作不会实际复制数据,而是通过形状转换来在内存中执行操作,因此它有助于节省内存。
- 广播限制: 当两个数组的维度在某个位置上不匹配且都不为1时,NumPy 将抛出错误。
二.Numpy 数组操作
1. ndarray.reshape
–改变数组形状
功能: 改变数组的形状。
语法:
ndarray.reshape(newshape, order='C')
参数:
newshape
: 整数或整数元组,定义新的形状。新的形状必须与原数组的元素总数相同。order
: 可选字符串,用于指定数据在内存中排列的顺序。可以是:'C'
:按行优先(默认)。'F'
:按列优先。'A'
:按列优先,如果数组是 Fortran 排列的,可以选择按行优先。
返回值: 返回一个新的数组,具有指定的形状。
示例:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = a.reshape((3, 2))
print(b) # 输出: [[1 2]
# [3 4]
# [5 6]]
#按列优先。
c = a.reshape((3,2),order="F")
print(c) #输出:[[1 5]
# [4 3]
# [2 6]]
2. ndarray.flat
–返回一个一维迭代器
功能: 返回一个一维迭代器,用于遍历数组中的每一个元素。
语法:
ndarray.flat
返回值: 返回一个一维迭代器,可以按需要进行遍历,也可以修改原数组中的元素。
示例:
import numpy as np
a = np.array([[1, 2], [3, 4]])
for x in a.flat:
print(x) # 输出: 1, 2, 3, 4
3. ndarray.flatten
– 展平数组
功能: 返回数组的一个连续扁平拷贝,降维。
语法:
ndarray.flatten(order='C')
参数:
order
: 可选字符串,用于指定数据在内存中排列的顺序,与reshape
方法相同。
返回值: 返回一个一维数组,包含原数组的所有元素。
示例:
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = a.flatten()
print(b) # 输出: [1 2 3 4]
a = np.arange(10).reshape(2,5)
print(a)# 输出:[[0 1 2 3 4]
# [5 6 7 8 9]]
print(a.flatten()) #[0 1 2 3 4 5 6 7 8 9]
4. ndarray.ravel
功能: 返回数组的一个扁平化视图(如果可能),否则返回一个拷贝。
语法:
ndarray.ravel(order='C')
参数:
- order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘K’ – 元素在内存中的出现顺序。
返回值: 返回一个一维数组的视图(如果可能),用来节省内存,尽量不复制数据,以节省内存。
示例:
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = a.ravel()
print(b) # 输出: [1 2 3 4]
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print (a.ravel())
print (a.ravel(order = 'F'))
# 原数组:
# [[0 1 2 3]
# [4 5 6 7]]
# [0 1 2 3 4 5 6 7]
# [0 4 1 5 2 6 3 7]
6. 数组转置
函数 | 描述 |
---|---|
transpose | 转置 |
ndarray.T | 转置 |
6.1、numpy.transpose
numpy.transpose 函数用于对换数组的维度,格式如下:
numpy.transpose(arr, axes)
参数说明:
arr
:要操作的数组axes
:整数列表,对应维度,通常所有维度都会对换。
"""transpose转置"""
import numpy as np
a = np.array([[1,2],[3,4],[5,6]],dtype=int)
print ("转置前:\n",a)
print ("转置后:\n",np.transpose(a))
# 转置前:
# [[1 2]
# [3 4]
# [5 6]]
# 转置后:
# [[1 3 5]
# [2 4 6]]
6.2ndarray.T
- 返回数组的转置(对二维数组进行转置)。
import numpy as np
a = np.array([[1,2,3],
[4,5,6]],dtype= int)
print ('原数组:')
print (a)
print ('转置数组:')
print (a.T)
7. 连接数组
7.1 numpy.concatenate
功能: 连接一系列数组。
语法:
numpy.concatenate((a1, a2, ...), axis=0, out=None)
参数:
a1, a2, ...
: 需要连接的数组序列,必须具有相同形状,除了在连接轴上。axis
: 连接的轴,默认为0
。–0是按行输出,–1是按列,可以设为None
,表示扁平化数组后连接。out
: 可选,提供一个输出数组,储存结果。
返回值: 返回连接后的新数组。
示例:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
c = np.concatenate((a, b))
print(c) # 输出: [1 2 3 4 5 6]
7.2 numpy.stack
功能: 在新轴上连接数组。
语法:
numpy.stack(arrays, axis=0, out=None)
参数:
arrays
: 要堆叠的输入数组,必须相同形状。axis
: 指定在新轴上进行堆叠,默认是0
。out
: 可选,提供一个输出数组。
返回值: 返回堆叠后的新数组。
示例:
"""stack连接数组"""
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
d = np.stack((a, b),axis=0)
c = np.stack((a, b),axis=1)
print("0是按行\n",d)
print("1是按列\n",c)
# 输出:
# 0是按行
# [[1 2 3]
# [4 5 6]]
# 1是按列
# [[1 4]
# [2 5]
# [3 6]]
7.3 numpy.hstack
功能: 水平(按列)堆叠数组。
语法:
numpy.hstack(tup)
参数:
tup
: 要水平堆叠的数组序列。
返回值: 返回一个水平堆叠后的新数组。
示例:
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
c = np.hstack((a, b.T))
print(c)
# 输出:
# [[1 2 5]
# [3 4 6]]
7.4 numpy.vstack
功能: 垂直(按行)堆叠数组。
语法:
numpy.vstack(tup)
参数:
tup
: 要垂直堆叠的数组序列。
返回值: 返回一个垂直堆叠后的新数组。
示例:
import numpy as np
a = np.array([1, 2])
b = np.array([3, 4])
c = np.vstack((a, b))
print(c)
# 输出:
# [[1 2]
# [3 4]]
2. 分割数组
7.1 numpy.split
功能: 将数组分割为多个子数组。
语法:
numpy.split(ary, indices_or_sections, axis=0)
参数:
ary
: 待分割的数组。indices_or_sections
: 指定分段的点或分割的数量。如果是整数,表示将数组分割成多少个小数组;如果是列表,表示在具体的位置分割。axis
: 沿着哪个轴分割,默认为0
,–0是按行输出,–1是按列。
返回值: 返回分割后的子数组列表。
示例:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6])
b = np.split(a, 3) #将数组分为三个大小相等的子数组
print(b) # 输出: [array([1, 2]), array([3, 4]), array([5, 6])]
b = np.split(a,[2,4])#将数组在一维数组中表明的位置分割
print (b) #[array([1, 2]), array([3, 4]), array([5, 6])]
7.2 numpy.hsplit
功能: 水平(按列)分割数组。
语法:
numpy.hsplit(ary, indices_or_sections)
参数:
ary
: 待分割的数组。indices_or_sections
: 指定分割点或分割的数量。
返回值: 返回分割后的子数组列表。
示例:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.hsplit(a, 3)
print(b)
# 输出:
# [array([[1],
# [4]]), array([[2],
# [5]]), array([[3],
# [6]])]
2.3 numpy.vsplit
功能: 垂直(按行)分割数组。
语法:
numpy.vsplit(ary, indices_or_sections)
参数:
ary
: 待分割的数组。indices_or_sections
: 指定分割点或分割的数量。
返回值: 返回分割后的子数组列表。
示例:
import numpy as np
a = np.arange(6).reshape(2,3)
b = np.vsplit(a,2)
print (a)
print (b)
# [[0 1 2]
# [3 4 5]]
# [array([[0, 1, 2]]), array([[3, 4, 5]])]
总结
-
连接数组的函数:
numpy.concatenate()
:连接多个数组。numpy.stack()
:在新轴上连接数组。numpy.hstack()
:水平堆叠数组。numpy.vstack()
:垂直堆叠数组。
-
分割数组的函数:
numpy.split()
:将数组分割为多个子数组。numpy.hsplit()
:水平分割数组。numpy.vsplit()
:垂直分割数组。
三.NumPy 副本和视图
视图(Views)和副本(Copies)
-
视图:
- 视图是原始数组的一个切片或视图(subarray),它与原数组共享相同的数据内存。
- 修改视图中的数据会影响原数组,反之亦然。
-
副本:
- 副本是原始数组数据的一个拷贝,修改副本不会影响原数组。
- 使用
numpy.copy()
或者切片等方法可以创建副本。
示例
import numpy as np
# 创建一个 NumPy 数组
arr = np.array([1, 2, 3, 4, 5])
# 创建一个视图
view = arr[1:4] # 这个切片创建了对 arr 的一个视图
print(arr) #[1 2 3 4 5]
print(view) # [2 3 4]
# 修改视图
view[0] = 99
print(view) # [99 3 4]
print(arr) # Output: [ 1 99 3 4 5]
# 创建副本
copy = arr.copy()
copy[0] = 123
print(copy) # Output: [123 99 3 4 5]
print(arr) # Output: [ 1 99 3 4 5]
深拷贝与浅拷贝
-
浅拷贝(Shallow Copy):
- 浅拷贝创建一个新对象,但不复制嵌套对象的内容(例如,二维数组中的观念)。
- 在 NumPy 中,切片操作生成的视图可以被视为一种浅拷贝,因为它们共享原始数组的数据。
-
深拷贝(Deep Copy):
- 深拷贝会递归复制对象及其嵌套对象,确保新对象与原始对象完全独立。
- 在 NumPy 中,使用
numpy.copy()
生成的副本可以被视为深拷贝,尽管 NumPy 不直接提供深拷贝的概念,因为它不支持嵌套对象。
四.random
随机数模块
- random模块是 Python 标准库中用于生成随机数和进行随机选择的模块。
1. 导入模块
在使用 random
模块之前,需要导入它:
import random
2. 生成随机浮点数
-
random.random()
: 生成一个 [0.0, 1.0) 之间的随机浮点数。num = random.random()
-
random.uniform(a, b)
: 生成一个 [a, b] 之间的随机浮点数,范围包括 a 和 b。num = random.uniform(1.5, 10.5)
3. 生成随机整数
-
random.randint(a, b)
: 生成一个 [a, b] 之间的随机整数,包括端点。num = random.randint(1, 100)
-
random.randrange(start, stop[, step])
: 生成一个 [start, stop) 之间的随机整数,可以指定步长。num = random.randrange(1, 100, 2) # 生成奇数
4. 从序列中随机选择
-
random.choice(sequence)
: 从非空序列中随机选择一个元素。item = random.choice(['apple', 'banana', 'cherry'])
-
random.sample(population, k)
: 从总体中随机选择 k 个不重复的元素。items = random.sample(['apple', 'banana', 'cherry'], 2)
5. 随机打乱序列
-
random.shuffle(x)
: 随机打乱可变序列(如列表)中的元素。该操作是在原序列上进行的,没有返回值。fruits = ['apple', 'banana', 'cherry'] random.shuffle(fruits)
6. 随机种子
-
random.seed(a=None)
: 设置随机数生成的种子。相同的种子会导致相同的随机数序列。random.seed(42)
7. 产生多个随机数
-
你可以使用列表推导式等方法产生多个随机数。
random_numbers = [random.random() for _ in range(5)] # 生成5个随机浮点数
8. 其他有用函数
-
random.getrandbits(k)
: 生成 k 位的随机整数。num = random.getrandbits(4) # 生成一个4位的随机二进制数
-
random.choice()
: 从任何非空序列中随机选择一个元素。 -
random.choices(population, weights=None, k=1)
: 从总体中选择 k 个元素,可以指定权重。choices = random.choices(['apple', 'banana', 'cherry'], weights=[0.1, 0.5, 0.4], k=10) #weights为概率,k为次数
9. 用法示例
import random
# 生成随机浮点数
print("随机浮点数:", random.random())
print("随机浮点数 (1.5, 10.5):", random.uniform(1.5, 10.5))
# 生成随机整数
print("随机整数 (1, 100):", random.randint(1, 100))
print("随机整数 (1, 100):", random.randrange(1, 100))
# 从序列中随机选择
fruits = ['apple', 'banana', 'cherry', 'date']
print("随机选择:", random.choice(fruits))
print("随机选择三个:", random.sample(fruits, 3))
# 随机打乱序列
random.shuffle(fruits)
print("打乱后的水果列表:", fruits)
# 设置随机种子
random.seed(42) # 设定随机种子
print("使用种子后的随机整数 (1, 100):", random.randint(1, 100))
random
模块提供了全面的 API 用于生成随机数和进行随机选择,适用于模拟、抽样、游戏等多种场景。了解其使用方法可以帮助你有效地在 Python 程序中实现随机功能。
五.数学函数
1、三角函数
- NumPy 提供了标准的三角函数:sin()、cos()、tan()。
angles = np.array([0, np.pi/2, np.pi])
print(np.sin(angles)) # 计算正弦
print(np.cos(angles)) # 计算余弦
print(np.tan(angles)) # 计算正切
2、舍入函数
numpy.around() 函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
参数说明:
- a: 数组
- decimals: 舍入的小数位数。 默认值为0。 如果为负,整数将四舍五入到小数点左侧的位置
import numpy as np
a = np.array([1.0,5.55, 123, 0.567, 25.532])
print (a)
print (np.around(a))
print (np.around(a, decimals = 1))
print (np.around(a, decimals = -1))
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
import numpy as np
a = np.array([-1.7, 1.5, -0.2, 0.6, 10])
print (a)
print (np.floor(a))
numpy.ceil() 返回大于或者等于指定表达式的最小整数,即向上取整。
import numpy as np
a = np.array([-1.7, 1.5, -0.2, 0.6, 10])
print (a)
print (np.ceil(a))
3.计算函数
1. numpy.reciprocal()
功能: 计算给定数组中每个元素的倒数。
语法:
numpy.reciprocal(x, out=None)
-
参数:
x
: 输入数组,可以是任何数组类型。out
: 可选的输出数组,指定存放结果的数组。
-
返回: 返回每个元素的倒数(即
1/x
),类型根据输入的类型决定。
示例:
import numpy as np
array = np.array([1, 2, 3, 4])
reciprocals = np.reciprocal(array)
print(reciprocals) # 输出: [1. 0.5 0.33333333 0.25 ]
2. numpy.power()
功能: 计算数组中每个元素的幂(即 x^y
),可以对数组中的每个元素进行幂运算。
语法:
numpy.power(a, b, out=None)
-
参数:
a
: 输入数组,可以是任何数组类型。b
: 代表幂的数组或标量,和a
必须具有相同的形状。out
: 可选的输出数组,指定存放结果的数组。
-
返回: 返回
a
中每个元素的b
次幂。
示例:
import numpy as np
base = np.array([1, 2, 3, 4])
exponent = 2
result = np.power(base, exponent)
print(result) # 输出: [ 1 4 9 16]
3. numpy.mod()
功能: 计算元素级别的模(取余)运算,返回 a
除以 b
的余数。
语法:
numpy.mod(a, b, out=None)
-
参数:
a
: 输入数组,可以是任何数组类型。b
: 另一个输入数组或标量,与a
的形状可以不同,但满足广播规则。out
: 可选的输出数组,指定存放结果的数组。
-
返回: 返回
a
除以b
的余数。
示例:
import numpy as np
array = np.array([10, 20, 30, 40])
divisor = 6
result = np.mod(array, divisor)
print(result) # 输出: [4 2 0 4]
小结
numpy.reciprocal()
计算倒数。numpy.power()
计算幂运算。numpy.mod()
计算模运算。
六.NumPy 矩阵库
- NumPy 矩阵库(
numpy.matrix
)是 NumPy 提供的一种特定于二维数组的对象,用于进行线性代数运算。与标准的 NumPy 数组 (numpy.ndarray
) 相比,矩阵有一些专门的功能和操作,主要是线性代数方面。
主要特点
- 二维矩阵:
numpy.matrix
是专门针对二维的,所以所有的numpy.matrix
对象都是 2D 的。 - 运算符重载: 矩阵使用
*
进行矩阵乘法运算,而numpy.ndarray
使用@
运算符或者numpy.dot()
进行矩阵乘法。 - 内置的线性代数操作: 矩阵对象具有直接支持的线性代数操作,比如求逆、转置等。
创建矩阵
使用 numpy.matrix()
import numpy as np
# 从列表创建矩阵
m = np.matrix([[1, 2], [3, 4]])
print(m)
使用 numpy.array()
并转为矩阵
# 从数组创建矩阵
m2 = np.matrix(np.array([[5, 6], [7, 8]]))
print(m2)
矩阵的基本操作
-
转置
m_transpose = m.T print(m_transpose)
-
逆矩阵
m_inv = m.I # 或者可以使用 np.linalg.inv(m) print(m_inv)
-
矩阵乘法
m3 = m * m2 # 使用 * 进行矩阵乘法 print(m3) m4 = m @ m2 # 使用 @ 进行矩阵乘法 print(m4)
-
求行列式
determinant = np.linalg.det(m) print(determinant)
-
求特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(m) print("Eigenvalues:", eigenvalues) print("Eigenvectors:", eigenvectors)
注意事项
-
稀疏矩阵: 对于大型稀疏矩阵,推荐使用 SciPy 的
scipy.sparse
模块,因为numpy.matrix
并不是专门为处理稀疏矩阵而设计的。 -
与 ndarray 的兼容性:
numpy.matrix
具有自己的功能,但 NumPy 的大多数函数支持ndarray
,因此在某些情况下,使用ndarray
可能会更方便。 -
选择
ndarray
还是matrix
: 由于numpy.matrix
已经不再推荐使用,更多的用户和文档都推荐使用numpy.ndarray
。特别是由于numpy.ndarray
支持多维数组,功能更加灵活。
示例
import numpy as np
# 创建一个 2x2 矩阵
A = np.matrix([[1, 2], [3, 4]])
print("Matrix A:")
print(A)
# 获取转置矩阵
A_T = A.T
print("Transpose of A:")
print(A_T)
# 计算逆矩阵
A_inv = A.I
print("Inverse of A:")
print(A_inv)
# 进行矩阵乘法
B = np.matrix([[5, 6], [7, 8]])
C = A * B
print("Matrix multiplication (A * B):")
print(C)
七.线性代数函数
1. dot
np.dot()
是一个通用的点乘函数,可以用于一维数组(向量)和二维数组(矩阵)。
-
语法:
np.dot(a, b)
-
示例:
import numpy as np A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 矩阵乘法 C = np.dot(A, B) print(C) # 输出:[[19 22] # [43 50]] # 向量点乘 x = np.array([1, 2]) y = np.array([3, 4]) result = np.dot(x, y) print(result) # 输出:11
2. vdot
np.vdot()
计算两个向量的虚点积(即共轭乘积),适用于复数向量。
-
语法:
np.vdot(a, b)
-
示例:
x = np.array([1, 2, 3]) y = np.array([4, 5, 6]) result = np.vdot(x, y) print(result) # 输出:32
3. inner
np.inner()
计算两个数组的内积。对于一维数组,内积与点乘相同,且在多维情况下,可以进行广播。
-
语法:
np.inner(a, b)
-
示例:
x = np.array([1, 2, 3]) y = np.array([4, 5, 6]) result = np.inner(x, y) print(result) # 输出:32
4. matmul
np.matmul()
则是专门用于矩阵乘法。与 dot()
不同的是,它对多维数组的行为更明确。
-
语法:
np.matmul(a, b)
-
示例:
A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) C = np.matmul(A, B) print(C) # 输出:[[19 22] # [43 50]]
5. det
np.linalg.det()
计算方阵的行列式。
-
语法:
np.linalg.det(a)
-
示例:
A = np.array([[1, 2], [3, 4]]) determinant = np.linalg.det(A) print(determinant) # 输出:-2.0
6. solve
np.linalg.solve()
用于求解线性方程组 (Ax = b)。
-
语法:
np.linalg.solve(a, b)
-
示例:
A = np.array([[3, 2], [1, 4]]) b = np.array([8, 9]) x = np.linalg.solve(A, b) print(x) # 输出:[2. 1.]
7. inv
np.linalg.inv()
计算方阵的逆矩阵。
-
语法:
np.linalg.inv(a)
-
示例:
A = np.array([[4, 7], [2, 6]]) inv_A = np.linalg.inv(A) print(inv_A) # 输出:[[ 0.6 -0.7] # [-0.2 0.4]]