📌 写在前面
大家好!👋
欢迎来到**【一起学Python】**的第81天!🎉
前80天,我们从安装环境开始,一步步掌握了数据类型、数组属性、创建方法、切片索引和高级索引。今天,我们要解锁NumPy最核心的威力——数组运算与广播机制!
🤔 为什么要学数组运算?
- ✅ 向量化计算:一行代码替代10行for循环,速度提升10-100倍!
- ✅ 广播机制:不同形状的数组也能直接运算,代码简洁到飞起!
- ✅ 聚合函数:求和、均值、最值...统计计算一键搞定!
- ✅ 数据分析师必备:90%的数据处理都靠这些基础运算!
今天你将学到:
- 🔸 数组的加减乘除与数学函数
- 🔸 广播机制(Broadcasting)核心原理
- 🔸 矩阵乘法 vs 元素级乘法
- 🔸 sum/mean/min/max等聚合函数实战
准备好了吗?让我们开始吧!🚀
一、数组的基本运算:元素级操作 🔢
NumPy的运算都是**元素级(element-wise)**的,即每个操作都应用于数组中对应位置的元素。
1.1 加减乘除四则运算
import numpy as npa = np.array([1, 2, 3])b = np.array([4, 5, 6])# 加法:对应元素相加print("a + b:", a + b) # [5 7 9]# 减法:对应元素相减print("b - a:", b - a) # [3 3 3]# 乘法:对应元素相乘(⚠️不是矩阵乘法!)print("a * b:", a * b) # [4 10 18]# 除法:对应元素相除print("b / a:", b / a) # [4. 2.5 2. ]
1.2 标量运算:数组 × 单个数
arr = np.array([1, 2, 3, 4, 5])# 数组 + 标量:每个元素都+10print("arr + 10:", arr + 10) # [11 12 13 14 15]# 数组 × 标量:每个元素都×2print("arr * 2:", arr * 2) # [ 2 4 6 8 10]# 数组 ** 标量:每个元素都平方print("arr ** 2:", arr ** 2) # [ 1 4 9 16 25]
💡 核心优势:无需写for循环,NumPy底层用C实现,速度飞快!
1.3 常用数学函数
arr = np.array([1, 4, 9, 16, 25])# 开平方print("平方根:", np.sqrt(arr)) # [1. 2. 3. 4. 5.]# 指数运算print("e的x次方:", np.exp(arr[:3])) # [ 2.718 54.598 8103.084]# 对数运算print("自然对数:", np.log(arr[:3])) # [0. 1.386 2.197]# 三角函数angles = np.array([0, np.pi/2, np.pi])print("sin值:", np.sin(angles)) # [0. 1. 0.]
二、广播机制(Broadcasting):不同形状也能算!🎯
广播是NumPy的灵魂特性,它允许不同形状的数组直接进行运算!
2.1 广播的三大规则
📐 广播规则(从后往前对比维度):1️⃣ 如果维度数不同,小数组前面补12️⃣ 如果某维度大小为1,可沿该维度"复制"扩展3️⃣ 如果某维度大小不同且都不为1 → 报错!
2.2 实战示例1:1维数组 + 2维数组
# 2维数组 (2行3列)a = np.array([[1, 2, 3], [4, 5, 6]])# 1维数组 (3个元素)b = np.array([10, 20, 30])# b会自动"广播"到与a相同的形状result = a + bprint("广播加法结果:\n", result)
📊 运算过程可视化:
原始: 广播后:[[1,2,3], [[1,2,3], + [[10,20,30], [4,5,6]] + [4,5,6]] [10,20,30]] ↓结果: [[11,22,33], [14,25,36]]
2.3 实战示例2:列向量 + 行向量
# 列向量 (3行1列)col = np.array([[1], [2], [3]]) # shape: (3, 1)# 行向量 (1行3列)row = np.array([10, 20, 30]) # shape: (1, 3)# 广播后变成 3×3 的矩阵!result = col + rowprint("列+行广播结果:\n", result)
[[11 21 31] [12 22 32] [13 23 33]]
💡 应用场景:快速生成坐标网格、距离矩阵、评分表等!
2.4 广播失败的情况 ⚠️
a = np.array([[1, 2, 3]]) # shape: (1, 3)b = np.array([[1], [2]]) # shape: (2, 1)# 这个可以!(1,3) + (2,1) → (2,3)print(a + b) # ✅ 成功# 但这个不行!c = np.array([1, 2, 3, 4]) # shape: (4,)d = np.array([[1, 2]]) # shape: (1, 2)# print(c + d) # ❌ ValueError: 维度不兼容!
三、矩阵乘法 vs 元素级乘法 🧮
新手最容易混淆的两个概念!
3.1 元素级乘法(*)
a = np.array([[1, 2], [3, 4]])b = np.array([[5, 6], [7, 8]])# * 是元素级乘法:对应位置相乘print("元素级乘法:\n", a * b)# 输出:# [[ 5 12]# [21 32]]
3.2 矩阵乘法(@ 或 dot)
# @ 或 np.dot() 是矩阵乘法:行列相乘求和print("矩阵乘法:\n", a @ b)# 或print("矩阵乘法:\n", np.dot(a, b))# 输出:# [[19 22]# [43 50]]
1×5 + 2×7 = 5 + 14 = 19 ✅
3.3 快速对比表
┌─────────────┬──────────────┬──────────────┐│ 运算符 │ 含义 │ 形状要求 │├─────────────┼──────────────┼──────────────┤│ * │ 元素级乘法 │ 形状相同/可广播││ @ │ 矩阵乘法 │ (m,n)×(n,p)→(m,p)││ np.dot() │ 矩阵乘法 │ 同@ │└─────────────┴──────────────┴──────────────┘
四、聚合函数:一键统计 📊
NumPy提供了一系列聚合函数,快速计算数组的统计特征。
4.1 基础聚合函数
arr = np.array([[1, 2, 3], [4, 5, 6]])# 求和print("总和:", np.sum(arr)) # 21# 平均值print("均值:", np.mean(arr)) # 3.5# 最小值/最大值print("最小值:", np.min(arr)) # 1print("最大值:", np.max(arr)) # 6# 标准差/方差print("标准差:", np.std(arr)) # 1.707...print("方差:", np.var(arr)) # 2.916...
4.2 按轴(axis)聚合:行/列统计
data = np.array([[10, 20, 30], [40, 50, 60]])# axis=0:沿列方向聚合(对每列计算)print("按列求和:", np.sum(data, axis=0)) # [50 70 90]# axis=1:沿行方向聚合(对每行计算)print("按行求和:", np.sum(data, axis=1)) # [60 150]# 求每列的平均值print("按列均值:", np.mean(data, axis=0)) # [25. 35. 45.]
💡 axis记忆口诀:
axis=0 → "压扁行",结果保留列axis=1 → "压扁列",结果保留行
4.3 其他实用聚合函数
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])# 累积求和print("累积和:", np.cumsum(arr)) # [3 4 8 9 14 23 25 31]# 累积乘积print("累积积:", np.cumprod(arr[:4])) # [3 3 12 12]# 排序print("排序后:", np.sort(arr)) # [1 1 2 3 4 5 6 9]# 中位数print("中位数:", np.median(arr)) # 3.5
📝 今日作业
基础题 ⭐
- 创建两个数组
[1,2,3] 和 [4,5,6],计算它们的和、差、积、商 - 使用广播机制,将1维数组
[10,20,30] 加到2维数组的每一行 - 计算数组
[1,4,9,16,25] 的平方根和自然对数
进阶题 ⭐⭐
- 创建一个3×4的随机数组,分别计算每行、每列的平均值
- 使用广播生成一个5×5的乘法表(无需循环!)
- 对比
arr * arr 和 arr @ arr 的结果差异(注意形状)
挑战题 ⭐⭐⭐
- 模拟学生成绩:100名学生×5门课程,计算:
- 每个学生的平均分(按行)
- 每门课的平均分(按列)
- 全班总平均分
- 使用广播计算两个点集之间的欧氏距离矩阵
- 实现"标准化":将数组转换为均值为0、标准差为1的分布
💡 参考代码(挑战题-标准化):
import numpy as np# 生成随机数据data = np.random.randn(100, 5) # 100×5的随机数# 标准化:(x - mean) / std# axis=0表示对每列(每门课)计算均值和标准差mean = np.mean(data, axis=0)std = np.std(data, axis=0)# 广播:data(100,5) - mean(5,) → 自动扩展normalized = (data - mean) / std# 验证:标准化后均值≈0,标准差≈1print("标准化后均值:", np.mean(normalized, axis=0))print("标准化后标准差:", np.std(normalized, axis=0))
🎓 明日预告
第82天:NumPy排序、搜索与集合操作
你将学到:
- 🔸
np.sort / np.argsort 排序技巧 - 🔸
np.where 条件搜索与定位 - 🔸
np.unique 去重与集合运算 - 🔸 实战:数据清洗中的高频操作
敬请期待! 🚀
💡 学习小贴士
- 运算选择指南:
- 元素级运算 → 直接用
+ - * / - 矩阵乘法 → 用
@ 或 np.dot() - 统计计算 → 用
np.sum/mean/std 等聚合函数
- 广播调试技巧:
- 形状对不上?先
print(arr1.shape, arr2.shape) - 不确定能否广播?手动按规则推演一遍
- 复杂广播?用小数组先测试逻辑
- 性能优化:
- 能用向量化就别写for循环
- 聚合运算时指定
axis避免多余计算 - 大数组运算前检查dtype,避免隐式转换
📚 学习路线图
第74天:NumPy安装 ✓第75天:ndarray对象 ✓第76天:数据类型 ✓第77天:数组属性 ✓第78天:创建数组 ✓第79天:切片和索引 ✓第80天:高级索引 ✓第81天:数组运算 ✓ ← 你今天在这里第82天:排序与搜索第83天:文件读写...
💬 写在最后
数组运算和广播机制是NumPy的核心武器,掌握它们,你就能:
✅ 用一行代码替代复杂循环✅ 优雅处理不同形状的数据✅ 快速完成统计分析与特征工程
今天重点掌握:
- ✅ 元素级运算与矩阵乘法的区别
- ✅ 广播机制的三条规则
- ✅ axis参数在聚合函数中的用法
如果觉得有用,记得:
- 👍 点赞支持一下
- ⭐ 收藏方便复习
- 📤 分享给更多小伙伴
完成作业的同学,欢迎在评论区打卡! 💪
【一起学Python】每天进步一点点,365天后遇见更优秀的自己!
👉 关注公众号,不错过每天的学习内容!
🎯 今日金句:
"向量化是NumPy的灵魂,广播是它的翅膀。掌握它们,让数据计算飞起来!" ✈️
明天见!