NumPy 常用工具:统计、排序、缺失值处理

在上一篇中,我们掌握了 NumPy 的向量化运算和广播机制,这是数值计算的性能核心。而在实际的数据处理场景中,我们还需要解决「统计分析」「排序去重」「缺失值处理」等高频问题 ------ 这些正是本文要讲解的核心内容,也是 NumPy 从「基础运算」走向「实战应用」的关键。

一、统计分析工具:挖掘数据的特征

NumPy 提供了一套完整的统计函数,不仅能计算整体的统计指标,还能按指定轴(行 / 列)计算,满足不同维度的分析需求。

1. 描述性统计函数

除了上篇提到的 sum()​/mean()​/max()​/min()​,以下是实战中更常用的描述性统计函数:

python

复制代码
import numpy as np

# 创建模拟数据(4行3列)
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9],
                [10, 11, 12]])

# 1. 中位数:np.median()
median_all = np.median(arr)          # 整个数组的中位数
median_axis0 = np.median(arr, axis=0)# 按列计算中位数
median_axis1 = np.median(arr, axis=1)# 按行计算中位数

# 2. 标准差与方差:np.std() / np.var()
std_all = np.std(arr)                # 整体标准差
std_axis1 = np.std(arr, axis=1)      # 每行标准差
var_all = np.var(arr)                # 整体方差

# 3. 百分位数:np.percentile()(常用25%、50%、75%分位数)
p25 = np.percentile(arr, 25)         # 25%分位数
p50 = np.percentile(arr, 50)         # 50%分位数(等价于中位数)
p75 = np.percentile(arr, 75)         # 75%分位数
p_axis0 = np.percentile(arr, 50, axis=0)  # 按列计算50%分位数

# 4. 最值索引:np.argmax() / np.argmin()(返回索引而非值)
argmax_all = np.argmax(arr)          # 整体最大值的扁平化索引
argmax_axis0 = np.argmax(arr, axis=0)# 每列最大值的行索引
argmin_axis1 = np.argmin(arr, axis=1)# 每行最小值的列索引

2. 累计统计函数

累计统计函数可以计算「累加」「累乘」等趋势性指标,常用于时序数据或序列分析:

python

复制代码
arr = np.array([1, 2, 3, 4, 5])

# 1. 累计求和:np.cumsum()
cumsum_arr = np.cumsum(arr)          # 逐个累加,结果为[1,3,6,10,15]

# 2. 累计乘积:np.cumprod()
cumprod_arr = np.cumprod(arr)        # 逐个累乘,结果为[1,2,6,24,120]

# 3. 二维数组的累计统计(指定轴)
arr2d = np.array([[1,2], [3,4]])
cumsum_axis0 = np.cumsum(arr2d, axis=0)  # 按列累计求和
cumsum_axis1 = np.cumsum(arr2d, axis=1)  # 按行累计求和

二、排序与去重:整理数据的秩序

数据处理中常需要对数组排序、提取唯一值,NumPy 提供了简洁高效的工具,避免手动写排序逻辑。

1. 数组排序

NumPy 排序分为「原地排序」和「返回新数组排序」,核心区别是是否修改原数组:

python

复制代码
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])
arr2d = np.array([[5, 2, 8], [3, 7, 1]])

# 1. np.sort():返回新数组(原数组不变)
sorted_arr = np.sort(arr)            # 一维数组升序排序
sorted_axis0 = np.sort(arr2d, axis=0)# 二维数组按列排序
sorted_axis1 = np.sort(arr2d, axis=1)# 二维数组按行排序
sorted_desc = np.sort(arr)[::-1]     # 降序排序(升序后反转)

# 2. arr.sort():原地排序(修改原数组)
arr_copy = arr.copy()
arr_copy.sort()                      # 原数组被修改

# 3. np.argsort():返回排序后的索引(而非值)
argsort_idx = np.argsort(arr)        # 升序索引
sorted_by_idx = arr[argsort_idx]     # 通过索引得到排序后数组

2. 去重与唯一值

​np.unique()​ 是去重的核心函数,支持返回唯一值、计数、原索引等信息:

python

复制代码
arr = np.array([2, 1, 3, 2, 1, 3, 4, 2, 5])
arr2d = np.array([[1,2,3], [2,3,4], [1,2,3]])

# 1. 基础去重:返回排序后的唯一值
unique_vals = np.unique(arr)         # 一维数组去重
unique_2d = np.unique(arr2d)         # 二维数组扁平化后去重

# 2. 返回唯一值的计数:return_counts=True
unique_vals, counts = np.unique(arr, return_counts=True)  # 值+对应出现次数

# 3. 返回唯一值的原索引:return_index=True
unique_vals, indices = np.unique(arr, return_index=True)  # 值+首次出现的索引

# 4. 判断元素是否在数组中:np.in1d()
mask = np.in1d(arr, [2, 3])          # 标记arr中属于[2,3]的元素
filtered_arr = arr[mask]             # 筛选出2和3的元素

三、缺失值与异常值处理:修复数据的瑕疵

实际数据中常存在缺失值(NaN)、无穷值(Inf)等异常,NumPy 提供了专门的检测和处理工具。

1. 缺失值的特性

NumPy 中用 np.nan​ 表示缺失值,需注意:

  • np.nan 是浮点型专属,整数数组中赋值 np.nan 会自动转为浮点型;
  • np.nan != np.nan,不能用 == 判断缺失值,必须用 np.isnan()。

python

复制代码
# 1. 创建含缺失值的数组
arr = np.array([1, 2, np.nan, 4, np.nan, 6], dtype=np.float64)
arr2d = np.array([[1, np.nan, 3], [np.nan, 5, 6]])

# 2. 检测缺失值:np.isnan()
nan_mask = np.isnan(arr)             # 标记缺失值位置
non_nan_mask = ~np.isnan(arr)        # 标记非缺失值位置

# 3. 检测无穷值:np.isinf()(Inf)
inf_arr = np.array([1, np.inf, -np.inf, 4])
inf_mask = np.isinf(inf_arr)         # 标记无穷值位置

# 4. 检测有限值:np.isfinite()(非NaN、非Inf)
finite_mask = np.isfinite(arr)       # 标记有限值位置

2. 缺失值的处理

缺失值处理的核心思路是「筛选删除」或「填充替换」:

python

复制代码
arr = np.array([1, 2, np.nan, 4, np.nan, 6], dtype=np.float64)
arr2d = np.array([[1, np.nan, 3], [np.nan, 5, 6]])

# 1. 筛选删除缺失值(返回一维数组)
non_nan_arr = arr[~np.isnan(arr)]    # 仅保留非缺失值

# 2. 填充缺失值:np.where()
filled_arr = np.where(np.isnan(arr), 0, arr)  # 缺失值填充为0
filled_mean = np.where(np.isnan(arr), np.nanmean(arr), arr)  # 填充为非缺失值的均值

# 3. 按轴填充缺失值(二维数组)
# 按列填充均值
col_means = np.nanmean(arr2d, axis=0)
filled_axis0 = np.where(np.isnan(arr2d), col_means, arr2d)

# 按行填充中位数
row_medians = np.nanmedian(arr2d, axis=1).reshape(-1, 1)  # 重塑维度以匹配广播
filled_axis1 = np.where(np.isnan(arr2d), row_medians, arr2d)

四、其他高频工具:解决场景化需求

除了上述核心工具,以下函数在实战中也频繁用到,能大幅简化代码:

1. 重复数组:np.repeat () /np.tile ()

两者都能重复数组,但逻辑不同:

  • np.repeat():按元素重复(每个元素重复指定次数);
  • np.tile():按整体重复(数组作为整体重复指定次数)。

python

复制代码
arr = np.array([1, 2, 3])

# 1. np.repeat():元素级重复
repeat_2 = np.repeat(arr, 2)         # 每个元素重复2次:[1,1,2,2,3,3]
repeat_axis0 = np.repeat(arr.reshape(3,1), 2, axis=0)  # 按行重复

# 2. np.tile():整体级重复
tile_2 = np.tile(arr, 2)             # 数组整体重复2次:[1,2,3,1,2,3]
tile_2d = np.tile(arr.reshape(3,1), (2, 3))  # 二维重复:2行3列

2. 条件替换:np.where () /np.select ()

​np.where()​ 适合单条件替换,np.select()​ 适合多条件替换:

python

复制代码
arr = np.array([1, 2, 3, 4, 5, 6])

# 1. np.where():单条件
replace_1 = np.where(arr < 3, 0, arr)  # 小于3替换为0,否则保留原值
replace_2 = np.where(arr % 2 == 0, 'even', 'odd')  # 偶数标even,奇数标odd

# 2. np.select():多条件
conditions = [arr < 2, arr < 5, arr >=5]
choices = ['small', 'medium', 'large']
replace_multi = np.select(conditions, choices)  # 按条件匹配替换值

3. 数组比较:np.all () /np.any ()

用于判断数组元素是否满足条件,返回布尔值:

python

复制代码
arr = np.array([1, 2, 3, 4])
arr2d = np.array([[True, False], [True, True]])

# 1. np.any():任意一个元素满足条件则为True
any_true = np.any(arr2d)             # 是否有任意True
any_gt3 = np.any(arr > 3)            # 是否有元素大于3

# 2. np.all():所有元素满足条件则为True
all_true = np.all(arr2d)             # 是否全为True
all_lt5 = np.all(arr < 5)            # 是否所有元素小于5

# 3. 按轴判断
any_axis0 = np.any(arr2d, axis=0)    # 按列判断是否有True
all_axis1 = np.all(arr2d, axis=1)    # 按行判断是否全为True

五、小结

  1. 统计工具:除基础统计量外,np.percentile()(分位数)、np.cumsum()(累计求和)是实战高频函数,axis 参数控制计算维度;
  2. 排序去重:np.sort() 返回新数组,arr.sort() 原地排序,np.unique() 支持去重 + 计数,是数据整理的核心;
  3. 缺失值处理:用 np.isnan() 检测缺失值,避免直接用 == 判断,填充方式优先选「均值 / 中位数」或业务指定值;
  4. 场景化工具:np.repeat()/np.tile() 处理数组重复,np.select() 实现多条件替换,np.all()/np.any() 批量判断条件。

下一篇预告:《NumPy 实战:从基础到场景化应用》------ 我们将整合前五篇的所有知识点,落地到数值模拟、数据标准化、图像处理、线性回归等实战场景,让你真正掌握 NumPy 的应用能力。

相关推荐
muddjsv20 小时前
NumPy 核心运算:向量化与广播
numpy
muddjsv20 小时前
NumPy 实战:从基础到场景化应用
numpy
A尘埃1 天前
Numpy常用方法介绍
numpy
belldeep2 天前
python:mnist 数据集下载,parse
python·numpy·mnist
佛祖让我来巡山3 天前
Numpy
机器学习·数据分析·numpy·矢量运算
纪伊路上盛名在3 天前
Chap1-1 Numpy手搓神经网络—入门PyTorch
pytorch·深度学习·神经网络·numpy·工程化
癫狂的兔子4 天前
【Python】【NumPy】random.rand和random.uniform的异同点
开发语言·python·numpy
清水白石0084 天前
《深度剖析 Pandas GroupBy:底层实现机制与性能瓶颈全景解析》
开发语言·python·numpy
纪伊路上盛名在5 天前
Chap1:Neural Networks with NumPy(手搓神经网络理解原理)
python·深度学习·神经网络·机器学习·numpy·计算生物学·蛋白质