
1. NumPy二维数组的创建方法第一次接触NumPy二维数组时我完全被它强大的功能震撼到了。记得当时需要处理一个简单的学生成绩表用Python原生列表操作起来特别麻烦直到发现了NumPy这个神器。今天我就把自己这些年积累的NumPy二维数组使用经验分享给大家保证让你少走弯路。创建二维数组最基础的方法就是从Python列表转换。比如我们要创建一个3x3的矩阵import numpy as np matrix np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])这个方法简单直接但有个小坑要注意列表中的每个子列表长度必须一致否则会创建出一个包含列表的对象数组而不是规整的二维数组。我曾经就因为这个踩过坑调试了半天才发现问题。更专业的做法是使用NumPy提供的专用创建函数。比如np.zeros()可以创建全零数组zeros_matrix np.zeros((3, 4)) # 创建3行4列的全零矩阵np.ones()则是创建全1数组用法类似。这两个函数特别适合做初始化我经常用它们来预分配内存空间比动态扩展列表效率高多了。如果需要创建指定范围的数值序列np.arange()配合reshape()是个好选择seq_matrix np.arange(12).reshape(3, 4) # 创建0-11的3x4矩阵这里有个实用技巧reshape时可以用-1来自动计算某一维的大小。比如np.arange(12).reshape(3, -1)会自动计算出列数为4。随机数组在实际项目中特别有用。NumPy提供了多种随机生成方式random_matrix np.random.rand(3, 3) # 0-1均匀分布 normal_matrix np.random.randn(3, 3) # 标准正态分布 randint_matrix np.random.randint(0, 10, (3, 3)) # 指定范围的随机整数我经常用随机数组来做算法测试和模拟数据。比如测试一个图像处理算法时就可以先用随机数组模拟图像数据。2. 数组的索引与切片技巧掌握了创建方法后接下来就是如何高效地访问和修改数组元素了。NumPy的索引系统非常灵活但刚开始可能会有点晕我来帮你理清楚。最基本的索引方式就是行列下标matrix np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(matrix[1, 2]) # 输出6 (第2行第3列)注意NumPy使用从0开始的索引和Python列表一致。这里有个常见错误是把行列顺序搞反记住总是先行后列。切片操作是处理二维数组的利器。比如要获取前两行print(matrix[:2]) # 前两行获取第2列print(matrix[:, 1]) # 所有行的第2列我特别喜欢NumPy的步长切片功能比如每隔一行取一列print(matrix[::2, ::2]) # 每隔一行一列取样高级索引是NumPy的一大亮点。布尔型索引可以根据条件筛选数据mask matrix 5 print(matrix[mask]) # 输出大于5的元素这在数据清洗时特别有用比如可以快速筛选出异常值。花式索引(Fancy indexing)可以用整数数组来索引print(matrix[[0, 2], [1, 0]]) # 输出(0,1)和(2,0)位置的元素这个技巧在机器学习中提取特定样本时非常方便。3. 数组的数学运算NumPy最强大的地方在于它的向量化运算能力。传统的循环计算在NumPy中可以简化为一行代码。基本的算术运算都是元素级别的a np.array([[1, 2], [3, 4]]) b np.array([[5, 6], [7, 8]]) print(a b) # 对应元素相加 print(a * b) # 对应元素相乘(不是矩阵乘法)注意这里的乘法是元素相乘不是矩阵乘法。矩阵乘法要用np.dot()或运算符print(np.dot(a, b)) # 矩阵乘法 print(a b) # Python 3.5支持的矩阵乘法运算符统计运算在日常数据分析中必不可少data np.random.randn(100, 5) # 100个样本5个特征 print(np.mean(data, axis0)) # 计算每列的均值 print(np.std(data, axis1)) # 计算每行的标准差 print(np.sum(data)) # 所有元素求和axis参数特别重要axis0表示沿列计算axis1表示沿行计算。我刚开始经常搞混后来记成axis0是竖着压缩axis1是横着压缩就好记多了。广播机制是NumPy的另一个魔法特性。它允许不同形状的数组进行运算a np.array([[1, 2], [3, 4]]) b np.array([10, 20]) print(a b) # b被广播到与a相同的形状这个特性让我们可以避免很多显式的循环和复制操作代码既简洁又高效。4. 实用操作技巧在实际项目中掌握一些NumPy的高级技巧可以事半功倍。下面分享几个我常用的技巧。数组转置和轴交换matrix np.arange(6).reshape(2, 3) print(matrix.T) # 转置 print(matrix.swapaxes(0, 1)) # 交换轴处理缺失值时可以用掩码数组data np.array([1, 2, -999, 4]) masked_data np.ma.masked_equal(data, -999) print(masked_data.mean()) # 自动忽略缺失值数组拼接也很常用a np.array([[1, 2], [3, 4]]) b np.array([[5, 6]]) # 垂直拼接 print(np.vstack((a, b))) # 水平拼接 print(np.hstack((a, np.array([[7], [8]]))))内存优化方面NumPy提供了np.ascontiguousarray()来确保数组内存连续布局这对性能敏感的应用很重要。最后分享一个性能优化技巧尽量避免在循环中频繁操作NumPy数组尽量使用向量化操作。比如计算欧式距离矩阵# 不好的做法 def slow_dist_matrix(x): n len(x) dist np.zeros((n, n)) for i in range(n): for j in range(n): dist[i, j] np.sqrt(np.sum((x[i] - x[j])**2)) return dist # 好的向量化做法 def fast_dist_matrix(x): xx np.sum(x**2, axis1) xy np.dot(x, x.T) return np.sqrt(xx[:, None] xx - 2*xy)向量化版本通常能快几十甚至上百倍。我在处理大规模数据时这个技巧帮我节省了大量计算时间。