NumPy 库使用指南
目录一、数组属性与创建二、基础运算三、索引四、数组合并五、数组分割六、数组的复制 (copy)七、周期信号生成NumPy (Numerical Python) 是 Python 中用于科学计算的核心库。它提供了一个高性能的多维数组对象ndarray以及用于操作这些数组的大量工具。一、数组属性与创建数组 (ndarray)这是 NumPy 的核心数据结构用于存储同类型数据的多维容器。import numpy as np # 创建一维数组 a np.array([1, 2, 3, 4]) print(a) # 输出: [1 2 3 4] # 创建二维数组 b np.array([[1, 2, 3], [4, 5, 6]]) print(b) # 输出: # [[1 2 3] # [4 5 6]]数据类型 (dtype)指定数组中元素的数据类型如int32,float64,complex,bool_,object_等。创建时指定默认64或查看已有数组的数据类型。c np.array([1, 2, 3], dtypenp.float64) print(c.dtype) # 输出: float64维度 (ndim)返回数组的维数轴的数量。print(a.ndim) # 输出: 1 (一维) print(b.ndim) # 输出: 2 (二维)形状 (shape)返回一个元组表示数组在每个维度上的大小。print(a.shape) # 输出: (4,) (长度为4的一维数组) print(b.shape) # 输出: (2, 3) (2行3列的二维数组)元素总数 (size)返回数组中元素的总个数。print(a.size) # 输出: 4 print(b.size) # 输出: 6创建特定数组np.zeros(shape): 创建指定形状的数组元素全部填充为0。np.ones(shape): 创建指定形状的数组元素全部填充为1。np.empty(shape): 创建指定形状的数组元素初始值为内存中的随机值未初始化。np.arange([start,] stop[, step]): 创建等差序列的一维数组类似于 Python 的range但返回数组。np.linspace(start, stop, num): 创建指定数量num个元素的等差序列一维数组在start和stop之间包含端点。np.random: 子模块用于生成随机数数组。np.random.rand(d0, d1, ..., dn): 生成在[0, 1)区间均匀分布的随机浮点数数组形状由参数指定。np.random.randn(d0, d1, ..., dn): 生成标准正态分布均值为0标准差为1的随机浮点数数组。np.random.randint(low, high, size): 生成在[low, high)区间内的随机整数数组形状由size指定。# 创建 2x3 的全零数组 zeros_arr np.zeros((2, 3)) print(zeros_arr) # 创建 3 个元素的全一数组 ones_arr np.ones(3) print(ones_arr) # 输出: [1. 1. 1.] # 创建未初始化的 2x2 数组 (值随机) empty_arr np.empty((2, 2)) print(empty_arr) # 创建从0到9的一维数组 arange_arr np.arange(10) print(arange_arr) # 输出: [0 1 2 3 4 5 6 7 8 9] # 创建从0到10包含10的5个等间隔点 linspace_arr np.linspace(0, 10, 5) print(linspace_arr) # 输出: [ 0. 2.5 5. 7.5 10. ] # 生成 2x2 的 [0, 1) 均匀分布随机数 rand_arr np.random.rand(2, 2) print(rand_arr) # 生成 3 个标准正态分布随机数 randn_arr np.random.randn(3) print(randn_arr) # 生成 5 个 [1, 10) 的随机整数 randint_arr np.random.randint(1, 10, 5) print(randint_arr)改变形状 (reshape)返回一个改变了形状的数组视图不改变原数据。新形状的元素总数必须与原数组相同。arr np.arange(12) # [0, 1, 2, ..., 11] reshaped_arr arr.reshape((3, 4)) # 变成 3行4列 print(reshaped_arr) # 输出: # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # 尝试错误形状会报错 # arr.reshape((3, 5)) # ValueError: cannot reshape array of size 12 into shape (3,5)二、基础运算NumPy 数组支持高效的向量化操作。逐个元素运算对数组中的每个元素进行相同的算术运算,-,*,/,**等、比较运算,!,,,,和逻辑运算,|,~。这些操作返回一个新的布尔数组或数值数组。a np.array([1, 2, 3]) b np.array([4, 5, 6]) # 加法 print(a b) # 输出: [5 7 9] # 乘法 (逐元素) print(a * b) # 输出: [4 10 18] # 平方 print(a ** 2) # 输出: [1 4 9] # 比较 print(a 2) # 输出: [False False True] print(a b) # 输出: [False False False] # 三角函数 (作用于每个元素) print(np.sin(a)) # 输出: [0.84147098 0.90929743 0.14112001]点乘 (np.dot,运算符)矩阵乘法。对于一维数组是内积对于二维数组是标准矩阵乘法。# 一维数组 (内积) vec1 np.array([1, 2]) vec2 np.array([3, 4]) dot_product np.dot(vec1, vec2) # 1*3 2*4 11 print(dot_product) # 输出: 11 # 或者使用 运算符 (Python 3.5) print(vec1 vec2) # 输出: 11 # 二维数组 (矩阵乘法) mat1 np.array([[1, 2], [3, 4]]) mat2 np.array([[5, 6], [7, 8]]) mat_product np.dot(mat1, mat2) # 或者 mat1 mat2 # 或者 mat1.dot(mat2) print(mat_product) # 输出: # [[19 22] # [43 50]] # 计算: [[1*52*7, 1*62*8], [3*54*7, 3*64*8]]聚合函数对整个数组或沿某个轴进行统计计算。np.sum(arr, axisNone): 求和。np.min(arr, axisNone),np.max(arr, axisNone): 最小值、最大值。np.mean(arr, axisNone): 平均值。np.average(arr, axisNone, weightsNone): 加权平均值。np.median(arr, axisNone): 中位数。np.cumsum(arr, axisNone): 累积和。np.argmin(arr, axisNone),np.argmax(arr, axisNone): 返回最小值、最大值所在位置的索引。axis参数指定计算沿哪个轴进行。axis0: 沿列垂直方向计算结果减少一个维度例如二维数组变成一维。axis1: 沿行水平方向计算。axisNone: 在整个数组上计算得到一个标量值。arr2d np.array([[1, 2, 3], [4, 5, 6]]) # 整个数组求和 total_sum np.sum(arr2d) print(total_sum) # 输出: 21 # 沿列求和 (axis0) - 计算每列的和 col_sum np.sum(arr2d, axis0) print(col_sum) # 输出: [5 7 9] (14, 25, 36) # 沿行求和 (axis1) - 计算每行的和 row_sum np.sum(arr2d, axis1) print(row_sum) # 输出: [6 15] (123, 456) # 最大值 print(np.max(arr2d)) # 输出: 6 # 沿列最大值 print(np.max(arr2d, axis0)) # 输出: [4 5 6] # 沿行最大值 print(np.max(arr2d, axis1)) # 输出: [3 6] # 平均值 print(np.mean(arr2d)) # 输出: 3.5 # 中位数 print(np.median(arr2d)) # 输出: 3.5 # 累积和 (整个数组展开) print(np.cumsum(arr2d)) # 输出: [ 1 3 6 10 15 21] # 最小值索引 (整个数组) print(np.argmin(arr2d)) # 输出: 0 (元素1在位置0) # 沿列最大值索引 print(np.argmax(arr2d, axis0)) # 输出: [1 1 1] (第0列最大值4在第1行第1列最大值5在第1行第2列最大值6在第1行)条件查找 (np.nonzero)返回数组中非零元素的索引。arr np.array([0, 1, 0, 3, 0, 5]) indices np.nonzero(arr) print(indices) # 输出: (array([1, 3, 5]),) 表示索引1, 3, 5处非零 print(arr[indices]) # 输出: [1 3 5] (使用这些索引获取非零值)排序 (np.sort)对数组进行排序默认升序。返回排序后的数组副本。arr np.array([3, 1, 4, 2]) sorted_arr np.sort(arr) print(sorted_arr) # 输出: [1 2 3 4] # 原数组不变 print(arr) # 输出: [3 1 4 2]转置 (np.transpose,.T属性)交换数组的维度。对于二维数组就是交换行和列。arr np.array([[1, 2], [3, 4], [5, 6]]) print(arr) # [[1 2] # [3 4] # [5 6]] print(arr.T) # 或者 np.transpose(arr) # [[1 3 5] # [2 4 6]]裁剪 (np.clip)将数组中的元素限制在指定的最小值和最大值范围内。小于min的值设为min大于max的值设为max。arr np.array([10, 5, 3, 15, 8]) clipped_arr np.clip(arr, 4, 12) print(clipped_arr) # 输出: [10 5 4 12 8] (3-4, 15-12)三、索引NumPy 提供了强大的索引功能。基本索引使用整数索引获取单个元素或切片类似于 Python 列表。对于多维数组使用逗号分隔的索引元组。arr np.array([0, 1, 2, 3, 4, 5]) print(arr[0]) # 输出: 0 print(arr[1:4]) # 输出: [1 2 3] (索引1到3) arr2d np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(arr2d[0]) # 输出: [1 2 3] (第0行) print(arr2d[0, 1]) # 输出: 2 (第0行第1列) print(arr2d[0:2]) # 输出: [[1 2 3] [4 5 6]] (第0行和第1行) print(arr2d[0:2, 1:3]) # 输出: [[2 3] [5 6]] (第0-1行第1-2列)布尔索引使用布尔数组通常由条件表达式生成来选择元素。arr np.array([5, 10, 15, 20, 25]) # 创建布尔数组: 哪些元素大于15? mask arr 15 print(mask) # 输出: [False False False True True] # 使用布尔索引选择元素 print(arr[mask]) # 输出: [20 25] # 一步完成 print(arr[arr 15]) # 输出: [20 25]花式索引 (Fancy Indexing)使用整数数组或列表来索引。返回一个副本而不是视图。arr np.arange(0, 10, 1) # [0,1,2,3,4,5,6,7,8,9] # 选择索引为 [2, 4, 6] 的元素 indices [2, 4, 6] print(arr[indices]) # 输出: [2 4 6] arr2d np.array([[1, 2], [3, 4], [5, 6], [7, 8]]) # 选择第0行和第2行 print(arr2d[[0, 2]]) # 输出: # [[1 2] # [5 6]]flat与flatten()numpy的flat属性提供迭代器遍历数组所有元素而flatten()方法返回展平后的一维数组副本。import numpy as np arr np.array([[1, 2], [3, 4]]) # 使用flat迭代元素 for element in arr.flat: print(element) # 输出: 1, 2, 3, 4 # 使用flatten()获取展平数组 flattened arr.flatten() print(flattened) # 输出: [1 2 3 4]四、数组合并将多个数组组合成一个更大的数组。垂直堆叠 (np.vstack)沿第一个轴行方向axis0堆叠数组。要求所有数组的列数相同。a np.array([1, 2, 3]) b np.array([4, 5, 6]) vstacked np.vstack((a, b)) print(vstacked) # 输出: # [[1 2 3] # [4 5 6]] c np.array([[1], [2], [3]]) d np.array([[4], [5], [6]]) vstacked2 np.vstack((c, d)) print(vstacked2) # 输出: # [[1] # [2] # [3] # [4] # [5] # [6]]水平堆叠 (np.hstack)沿第二个轴列方向axis1堆叠数组。要求所有数组的行数相同。a np.array([1, 2, 3]) b np.array([4, 5, 6]) hstacked np.hstack((a, b)) print(hstacked) # 输出: [1 2 3 4 5 6] c np.array([[1], [2], [3]]) d np.array([[4], [5], [6]]) hstacked2 np.hstack((c, d)) print(hstacked2) # 输出: # [[1 4] # [2 5] # [3 6]]增加新维度 (np.newaxis/None)用于在特定位置插入一个新的长度为1的轴改变数组的形状使其可以与其他数组进行堆叠或广播。a np.array([1, 2, 3]) print(a.shape) # (3,) # 将其变成行向量 (1 行, 3 列) row_vec a[np.newaxis, :] # 或者 a[None, :] print(row_vec) # 输出: [[1 2 3]] print(row_vec.shape) # (1, 3) # 将其变成列向量 (3 行, 1 列) col_vec a[:, np.newaxis] # 或者 a[:, None] print(col_vec) # 输出: # [[1] # [2] # [3]] print(col_vec.shape) # (3, 1) # 现在可以用 vstack/hstack 与其他数组合并 b np.array([4, 5, 6])[:, None] # 也变成列向量 hstacked_cols np.hstack((col_vec, b)) print(hstacked_cols) # 输出: # [[1 4] # [2 5] # [3 6]]通用连接 (np.concatenate)沿指定轴连接数组序列。功能比vstack和hstack更通用。np.concatenate((a1, a2, ...), axis0)a np.array([[1, 2], [3, 4]]) b np.array([[5, 6]]) # 沿行 (axis0) 连接要求列数相同 concat_rows np.concatenate((a, b), axis0) print(concat_rows) # 输出: # [[1 2] # [3 4] # [5 6]] # 沿列 (axis1) 连接要求行数相同 c np.array([[7], [8]]) concat_cols np.concatenate((a, c), axis1) print(concat_cols) # 输出: # [[1 2 7] # [3 4 8]]五、数组分割将一个数组拆分成多个较小的数组。均等分割 (np.split,np.array_split)np.split(ary, indices_or_sections, axis0): 将数组沿指定轴分割成多个子数组。indices_or_sections: 如果是一个整数N表示将数组均等分割成N份。如果是一个索引列表[i1, i2, ...]表示在索引i1,i2, ... 处进行分割。np.array_split(ary, indices_or_sections, axis0): 功能与split类似但允许不均等分割当不能整除时最后几个子数组会包含较少的元素。arr np.arange(10) # [0,1,2,3,4,5,6,7,8,9] # 均等分割成2份 (要求能整除) split_2 np.split(arr, 2) print(split_2) # [array([0,1,2,3,4]), array([5,6,7,8,9])] # 在索引3和7处分割 split_indices np.split(arr, [3, 7]) print(split_indices) # [array([0,1,2]), array([3,4,5,6]), array([7,8,9])] # 不均等分割成3份 (使用 array_split) arrsplit_3 np.array_split(arr, 3) print(arrsplit_3) # [array([0,1,2,3]), array([4,5,6]), array([7,8,9])] 或类似分布垂直分割 (np.vsplit)沿垂直方向行方向axis0分割数组。相当于split函数设置axis0。arr2d np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) # 分割成2个行数相等的数组 vsplit_2 np.vsplit(arr2d, 2) print(vsplit_2) # [array([[1, 2, 3], [4, 5, 6]]), array([[7, 8, 9], [10, 11, 12]])] # 在第2行处分割 vsplit_idx np.vsplit(arr2d, [2]) print(vsplit_idx) # [array([[1, 2, 3], [4, 5, 6]]), array([[7, 8, 9], [10, 11, 12]])] (同上)水平分割 (np.hsplit)沿水平方向列方向axis1分割数组。相当于split函数设置axis1。arr2d np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # 分割成2个列数相等的数组 hsplit_2 np.hsplit(arr2d, 2) print(hsplit_2) # [array([[1, 2], [5, 6]]), array([[3, 4], [7, 8]])] # 在第2列处分割 hsplit_idx np.hsplit(arr2d, [2]) print(hsplit_idx) # [array([[1, 2], [5, 6]]), array([[3, 4], [7, 8]])] (同上) # 不均等分割 (使用 array_split 或指定索引列表) hsplit_uneven np.hsplit(arr2d, [1, 3]) # 在索引1和3处分割 print(hsplit_uneven) # [array([[1], [5]]), array([[2, 3], [6, 7]]), array([[4], [8]])]六、数组的复制 (copy)NumPy 数组的赋值操作 (b a) 是浅拷贝。它不会创建新的数据副本而是让新变量b指向与原变量a相同的底层数据内存块。因此修改b也会改变a反之亦然。a np.array([1, 2, 3]) b a # b 是 a 的一个视图 (view)指向相同的数据 b[0] 99 # 通过 b 修改数据 print(a) # 输出: [99 2 3] # a 也被修改了! print(b) # 输出: [99 2 3]如果需要创建一个数组的独立副本深拷贝使其数据与原数组完全分离必须使用np.copy函数或数组的copy()方法a np.array([1, 2, 3]) c a.copy() # 或者 c np.copy(a) c[0] 99 # 修改 c 的数据 print(a) # 输出: [1 2 3] # a 保持不变 print(c) # 输出: [99 2 3]七、周期信号生成参数设置这里A1.0振幅为1f5频率5Hzfs1000采样频率1000HzT1信号持续1秒。采样点数计算为fs*T 1000。时间轴生成np.linspace(0, T, int(fs * T))创建一个从0到1秒的数组包含1000个等间隔点每个点间隔为0.001秒。信号计算np.sin(2 * np.pi * f * t)实现了公式s(t) sin(2pi*f*t)NumPy的广播机制自动处理数组运算。输出代码打印信号的前10个点便于验证。import numpy as np # 定义信号参数 A 1.0 # 振幅 f 5 # 频率Hz fs 1000 # 采样频率Hz T 1 # 持续时间秒 # 创建时间轴数组从0到T共fs*T个点 t np.linspace(0, T, int(fs * T)) # 生成正弦波信号 signal A * np.sin(2 * np.pi * f * t) # 打印前10个点示例 print(信号前10个点:, signal[:10])