NumPy 第 7 章:统计与聚合

本系列是《NumPy 速通》的配套章节。 对一整组数据算个总账——求和、均值、最大最小、方差等等。这些操作叫聚合(aggregation),因为它们把一堆数"聚合"成一个数。本章重点:axis 参数(90% 的坑都在这)和"忽略 NaN"的两个变体。 基本聚合函数 import numpy as np arr = np.array([3, 1, 4, 1, 5, 9, 2, 6]) np.sum(arr) # 31 总和 np.mean(arr) # 3.875 平均 np.max(arr) # 9 最大 np.min(arr) # 1 最小 np.std(arr) # 标准差(sqrt(方差)) np.var(arr) # 方差 np.median(arr) # 3.5 中位数(不受极端值影响) np.prod(arr) # 连乘 np.cumsum(arr) # [3 4 8 9 14 23 25 31] 累积和 💡 均值 vs 中位数:均值对极端值(outlier)敏感,中位数稳健。工资数据被几个富豪拉高时,用中位数更能反映"普通人"水平。np.cumsum(累积和)常用于画累积分布、算前缀和。 ⚠️ 灵魂警告:NaN 会污染聚合结果 data = np.array([1.0, 2.0, np.nan, 4.0]) np.mean(data) # nan ⚠️ 一个 nan 就毁掉整个均值! 解决方案——忽略 NaN 的版本(每个聚合函数都有): np.nanmean(data) # 2.333 忽略 nan 再平均 np.nansum(data) # 7.0 np.nanmax(data) # 4.0 np.nanstd(data) # 忽略 nan 的标准差 真实数据(传感器、爬虫、问卷)几乎必然有缺失值。先 np.isnan(data).any() 检查,再用 nan 系列函数,是数据清洗的基本功。 ...

2026-08-30 · OC

NumPy 第 8 章:广播机制

本系列是《NumPy 速通》的配套章节。 广播(Broadcasting)是 NumPy 最强大的特性,也是最难理解的。简单说:当两个形状不同的数组做运算时,NumPy 会自动把小的那个"扩展"到大数组的形状,然后逐元素运算——而且不占用额外内存。 类比:就像老师宣布"每人加 5 分",这个"5"会自动广播到每个学生的成绩上,不需要手动复制 5 很多遍。广播 = 写更少的代码 + 不复制数据(省内存)。 标量广播(最简单的广播) import numpy as np arr = np.array([1, 2, 3, 4, 5]) arr + 10 # [11 12 13 14 15] 原理:10 被"广播"成 [10, 10, 10, 10, 10],然后逐元素相加。这个展开是 NumPy 内部虚拟的,不占额外内存——所以它比 np.tile 或列表复制快得多、省得多。 数组与数组的广播 arr = np.array([[1, 2, 3], [4, 5, 6]]) # shape (2, 3) col = np.array([10, 20, 30]) # shape (3,) arr + col # (2,3) 和 (3,) → 广播成两行都加 # [[11 22 33] # [14 25 36]] (2,3) 和 (3,) 能直接相加——(3,) 从最后一个维度对齐,被广播成了两行。 ⚠️ 灵魂警告:对齐是从最后一个维度开始的! row = np.array([[10], [20]]) # shape (2, 1),想当"每列"用 arr + row # ❌ (2,3) + (2,1) → 按列加,不是按行! # 结果 (2, 3) 但每一列都加了 [10,20] 想"每行加同样的数"→ 用 (3,);想"每列加不同的数"→ 用 (3,1)(见下)。 ...

2026-08-30 · OC

NumPy 第 9 章:布尔索引与筛选

本系列是《NumPy 速通》的配套章节。 数据处理的日常:把满足条件的元素挑出来。NumPy 用布尔数组做索引,非常优雅,而且返回副本(不会污染原数据)。本章讲透:基本筛选、组合条件、二维行筛选、np.where、布尔统计。 基本筛选 import numpy as np arr = np.array([1, 2, 3, 4, 5]) arr[arr > 3] # [4 5] 取出所有大于 3 的元素 拆开看,它分两步: mask = arr > 3 # [False False False True True] 布尔数组 arr[mask] # [4 5] 只取 True 位置的元素 💡 返回的是副本:修改筛选结果不会影响原数组(和第 3 章花式索引一致)。比切片安全得多。 组合条件:& | ~ 用 &(与)、|(或)、~(非),每个条件都要加括号: arr[(arr > 2) & (arr < 5)] # [3 4] 大于 2 且小于 5 arr[(arr < 2) | (arr > 4)] # [1 5] 小于 2 或大于 4 arr[~(arr == 3)] # [1 2 4 5] 不等于 3 ⚠️ 灵魂警告: 不能用 Python 的 and / or(它们只认单个布尔值,不认数组)——必须用 & / | / ~(逐元素位运算) 每个条件必须加括号:(arr > 2) & (arr < 5)。写成 arr > 2 & arr < 5 会报错或算错(运算符优先级问题) 常见报错 The truth value of an array with more than one element is ambiguous 就是忘了这些导致的 二维数组:筛选行 / 列 data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 按某列条件筛行:第一列大于 3 的行 rows = data[data[:, 0] > 3] # [[4 5 6] # [7 8 9]] # 按行条件筛列:每行第一个元素大于 2 的列?不,是取列 data[:, data[0] > 2] # 第一行大于 2 的列 → 第 2、3 列 # [[2 3] # [5 6] # [8 9]] 口诀:data[行条件, :] 筛行;data[:, 列条件] 筛列。条件是布尔数组时,它充当对应维度的"开关列表"。 ...

2026-08-30 · OC