Python全栈开发-第7章NumPy/SciPy数值计算
第三篇 · 科学计算与AI🔢 第7章 NumPy/SciPy数值计算用Python驾驭海量数据的数学引擎7.1 NumPy数组入门从列表到ndarray,打开科学计算的大门想象你是一位厨师,Python列表是你的旧菜刀——什么都能切,但效率平平。而NumPy的ndarray就像一把瑞士军刀:它不仅能高效地切片、翻转、重组数据,还内置了整套数学运算工具。NumPy是Python科学计算的基石,Pandas、SciPy、TensorFlow全都建立在它之上。ndarray的核心优势在于连续内存和同质数据类型。Python列表存的是分散的对象指针,而ndarray把数据紧密排列在内存中,CPU缓存命中率大幅提升,计算速度可以快10~100倍。importnumpyasnp# ===== 创建数组的多种方式 =====# 从列表创建a=np.array([1,2,3,4,5])print('一维数组:',a)print('形状:',a.shape)# (5,)print('数据类型:',a.dtype)# int64# 创建二维数组(矩阵)b=np.array([[1,2,3],[4,5,6]])print('\n二维数组:\n',b)print('形状:',b.shape)# (2, 3)# ===== 快捷创建函数 =====zeros=np.zeros((3,4))# 全零矩阵 3x4ones=np.ones((2,3))# 全1矩阵 2x3eye=np.eye(4)# 4x4单位矩阵rng=np.arange(0,10,2)# [0, 2, 4, 6, 8]lin=np.linspace(0,1,5)# [0, 0.25, 0.5, 0.75, 1.0]print('\n全零矩阵:\n',zeros)print('单位矩阵:\n',eye)print('arange:',rng)print('linspace:',lin)🔑 核心要点ndarray的核心属性:shape(形状元组)、dtype(元素类型)、ndim(维度数)、size(元素总数)。创建数组时可用dtype参数显式指定类型,如np.array([1,2], dtype=np.float32)。importnumpyasnp# ===== dtype与类型转换 =====x=np.array([1.0,2.0,3.0],dtype=np.float64)y=np.array([1,2,3],dtype=np.int32)print('float64数组:',x,x.dtype)print('int32数组:',y,y.dtype)# 类型提升:int + float - floatz=x+yprint('相加结果:',z,'dtype:',z.dtype)# float64# ===== 形状操作 =====m=np.arange(12)# [0,1,2,...,11]print('\n原始:',m.shape)m2=m.reshape(3,4)# 变成3行4列print('reshape(3,4):\n',m2)m3=m.reshape(2,6)print('reshape(2,6):\n',m3)# -1表示自动推断该维度m4=m.reshape(4,-1)print('reshape(4,-1):\n',m4)# (4, 3)# flatten展平为一维flat=m2.flatten()print('\nflatten:',flat)💡 技巧reshape返回的是视图(view)而非副本,修改视图会影响原数组。如果需要独立副本,请使用 .copy()。另外,reshape(-1) 是展平数组的惯用写法,比 flatten() 更高效(不复制内存)。importnumpyasnp# ===== 广播机制 =====# 广播让不同形状的数组也能进行运算a=np.array([[1,2,3],[4,5,6]])# 形状 (2, 3)b=np.array([10,20,30])# 形状 (3,)# b被广播到每一行print('a + b:\n',a+b)# [[11, 22, 33],# [14, 25, 36]]# 标量也会广播print('a * 2:\n',a*2)# 列向量广播到每一列col=np.array([[100],[200]])# 形状 (2, 1)print('a + col:\n',a+col)# [[101, 102, 103],# [204, 205, 206]]# ===== 广播规则 =====# 1. 较短的维度向左补1# 2. 两个维度相等或其中一个为1时才能广播# 3. 输出形状取每个维度的最大值x=np.ones((3,1,4))# (3,1,4)y2=np.ones((1,1,4))# (1,1,4)result2=x+y2# - (3,1,4)print('广播结果形状:',result2.shape)⚠️ 注意广播不会复制数据,只是逻辑上扩展,所以非常高效。但如果广播产生了一个巨大的中间结果(比如两个10000x10000的矩阵相加),内存可能不够。务必在广播前检查形状是否合理!🧪 随堂测验以下代码的输出是什么?np.array([[1,2],[3,4]]).reshape(-1) 的结果是?A. array([1, 2, 3, 4])B. array([[1, 2], [3, 4]])C. 报错,-1不合法D. array([1, 3, 2, 4])答案解析:reshape(-1) 会将任意形状的数组展平为一维。ndarray默认按行优先(C顺序)展平,所以结果是 [1, 2, 3, 4]。7.2 向量与矩阵运算线性代数的Python实战如果说NumPy数组是数据容器,那么向量与矩阵运算就是科学计算的发动机。在机器学习中,一次前向传播可能涉及数百万次矩阵乘法;在物理学中,量子态的演化本质是矩阵变换。NumPy提供了丰富的线性代数工具:np.dot做点积,np.matmul(或@运算符)做矩阵乘法,np.linalg模块则封装了求逆、特征值、SVD等高级功能。掌握这些工具,你就拥有了科学计算的利器。importnumpyasnp# ===== 向量点积 =====a=np.array([1,2,3])b=np.array([4,5,6])dot=np.dot(a,b)# 1*4 + 2*5 + 3*6 = 32print('点积:',dot)# 也可以用 @ 运算符print('点积(@):',a @ b)# ===== 矩阵乘法 =====A=np.array([[1,2],[