Day 47:【99天精通Python】NumPy 进阶 - 维度变换与布尔索引
前言
欢迎来到第47天!
在昨天,我们已经掌握了 NumPy 数组的创建和基础运算。今天我们将继续深入,学习两个非常强大的功能:
- 维度变换:把一维的 12 个数字变成 3x4 的矩阵,或者反过来。这在图像处理(比如把图片拉平送入神经网络)中非常常见。
- 布尔索引 (Boolean Indexing):不通过下标,而是通过"条件"来取值。比如"找出所有不及格的分数"、“把所有负数变成0”。
这些技巧是数据清洗和预处理的核心技能。
本节内容:
reshape:改变形状flattenvsravel:扁平化- 转置 (Transpose)
- 数组拼接与分割
- 布尔索引与花式索引
- 实战练习:图像蒙版处理
一、维度变换
1.1 reshape:变身术
reshape可以改变数组的形状,但元素总数必须保持一致。
importnumpyasnp# 创建一个 0-11 的一维数组arr=np.arange(12)print(arr)# 变成 3行4列matrix=arr.reshape(3,4)print(matrix)# 变成 2行6列print(arr.reshape(2,6))# 使用 -1 自动计算维度# 我只指定要 4 行,列数你帮我算print(arr.reshape(4,-1))# 结果是 4x31.2 Flatten:拍扁
将多维数组变回一维数组。
matrix=np.array([[1,2,3],[4,5,6]])# flatten: 返回一份拷贝 (修改不影响原数组)flat=matrix.flatten()flat[0]=999print(matrix[0,0])# 依然是 1# ravel: 返回视图 (View, 修改会影响原数组)view=matrix.ravel()view[0]=999print(matrix[0,0])# 变成了 9991.3 转置 (Transpose)
矩阵的行变列,列变行。
matrix=np.arange(12).reshape(3,4)print(matrix)# [[ 0 1 2 3]# [ 4 5 6 7]# [ 8 9 10 11]]print(matrix.T)# [[ 0 4 8]# [ 1 5 9]# [ 2 6 10]# [ 3 7 11]]二、数组拼接
在数据预处理时,我们经常需要把多个数据集拼在一起。
vstack(Vertical Stack): 垂直拼接 (增加行)hstack(Horizontal Stack): 水平拼接 (增加列)
a=np.array([1,2,3])b=np.array([4,5,6])# 垂直拼接 (变成 2x3)print(np.vstack((a,b)))# [[1 2 3]# [4 5 6]]# 水平拼接 (变成 1x6)print(np.hstack((a,b)))# [1 2 3 4 5 6]三、神奇的索引
3.1 布尔索引 (Boolean Indexing)
这是 NumPy 最性感的特性之一。我们可以传入一个布尔数组来筛选数据。
场景:找出所有大于 5 的数。
data=np.array([1,8,3,9,2,7])# 1. 生成布尔数组mask=data>5print(mask)# [False True False True False True]# 2. 利用 mask 筛选print(data[mask])# [8 9 7]# 3. 一步到位 (常用)print(data[data>5])场景:把所有偶数替换为 0。
data[data%2==0]=0print(data)# [1 0 3 9 0 7]3.2 花式索引 (Fancy Indexing)
使用整数数组作为索引,一次性取出多个不连续的值。
arr=np.arange(10)*10# [0, 10, 20, ..., 90]# 取出第 1, 3, 5 个元素indices=[1,3,5]print(arr[indices])# [10 30 50]四、where 函数
np.where是 Excel 中IF函数的加强版。
语法:np.where(条件, 真值, 假值)
arr=np.array([10,20,30,40,50])# 如果大于 30,改为 1,否则为 0res=np.where(arr>30,1,0)print(res)# [0 0 0 1 1]# 如果大于 30,保持原值,否则改为 -1res2=np.where(arr>30,arr,-1)print(res2)# [-1 -1 -1 40 50]五、实战练习
练习1:成绩清洗
有一个学生成绩数组scores,包含一些无效值(-1 表示缺考)。
请计算有效成绩(>=0)的平均分。
scores=np.array([85,90,-1,78,-1,60,92])# 筛选有效成绩valid_scores=scores[scores>=0]print(f"有效成绩:{valid_scores}")print(f"平均分:{np.mean(valid_scores):.2f}")练习2:图像蒙版 (Mask) 模拟
假设一张图片是一个 5x5 的矩阵,数值 0-255。
请将所有亮度低于 100 的像素点(太暗的)全部提亮为 100。
# 生成随机图片数据img=np.random.randint(0,256,(5,5))print("原图:\n",img)# 处理:小于100的变成100img[img<100]=100print("处理后:\n",img)六、小结
关键要点:
- reshape是改变数组形状的神器,记得用
-1偷懒。 - 布尔索引是数据清洗的核心,一定要熟练掌握
arr[condition]这种写法。 - np.where能轻松实现批量条件替换。
七、课后作业
- 矩阵标准化:创建一个 10x5 的随机矩阵。将每一列的数据减去该列的平均值(中心化处理)。(提示:利用广播机制)。
- 双重条件筛选:生成 1 到 100 的数组。筛选出所有能被 3 整除且能被 5 整除的数。(提示:使用
&运算符,注意括号(cond1) & (cond2))。 - One-hot 编码:有一个标签数组
labels = [1, 0, 2, 1](类别总数为3)。请创建一个对应的 One-hot 矩阵(4x3),对应位置为 1,其余为 0。
下节预告
Day 48:数据分析 Pandas 入门- 终于到了重头戏!NumPy 虽然快,但看表格还是不直观。明天我们学习 Pandas 的 DataFrame,像操作 Excel 一样操作 Python 数据!
系列导航:
- 上一篇:Day 46 - 数据分析NumPy基础
- 下一篇:Day 48 - 数据分析Pandas入门(待更新)