Skip to content

常用函数 ​

NumPy 内置了数百个数学、统计和工具函数。本章整理了最常用的函数分类,涵盖聚合统计、随机数生成、集合操作和文件 I/O。

一、聚合与统计函数 ​

1、基础统计 ​

python
import numpy as np

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

print(np.sum(a))       # 45        — 求和
print(np.mean(a))      # 5.0       — 均值
print(np.median(a))    # 5.0       — 中位数
print(np.std(a))       # 2.58...   — 标准差(总体)
print(np.var(a))       # 6.67...   — 方差(总体)
print(np.min(a))       # 1         — 最小值
print(np.max(a))       # 9         — 最大值
print(np.ptp(a))       # 8         — 极差 (max - min)

样本标准差 vs 总体标准差

  • np.std(a) 默认 ddof=0,计算总体标准差
  • np.std(a, ddof=1) 计算样本标准差(除以 n-1)

在统计学和机器学习中,通常使用样本标准差 ddof=1。

2、分位数与百分位数 ​

python
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 百分位数
print(np.percentile(a, 50))    # 5.5     — 第 50 百分位(中位数)
print(np.percentile(a, [25, 75]))  # [3.25, 7.75] — 四分位数

# 分位数(0~1 之间)
print(np.quantile(a, 0.5))     # 5.5
print(np.quantile(a, [0.25, 0.75]))  # [3.25, 7.75]

3、累积统计 ​

python
a = np.array([1, 2, 3, 4, 5])

print(np.cumsum(a))    # [ 1  3  6 10 15]     — 累加和
print(np.cumprod(a))   # [  1   2   6  24 120] — 累乘积

# 差分
print(np.diff(a))      # [1 1 1 1]            — 相邻元素差
print(np.diff(a, n=2)) # [0 0 0]              — 二阶差分

4、条件统计 ​

python
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

# 非零元素个数
print(np.count_nonzero(a))       # 9

# 满足条件的元素个数
print(np.sum(a > 5))             # 4

# 非零元素的位置
print(np.nonzero(a > 5))         # (array([5, 6, 7, 8]),)

# where + 统计
result = np.where(a > 5, a, 0)
print(np.sum(result))            # 30

# 条件求和
print(np.sum(a[a > 5]))          # 30

二、集合操作 ​

python
a = np.array([1, 2, 3, 4, 5])
b = np.array([3, 4, 5, 6, 7])

# 去重
print(np.unique([1, 1, 2, 3, 3, 3]))  # [1 2 3]

# 并集
print(np.union1d(a, b))        # [1 2 3 4 5 6 7]

# 交集
print(np.intersect1d(a, b))    # [3 4 5]

# 差集(a 中有但 b 中没有)
print(np.setdiff1d(a, b))      # [1 2]

# 对称差集(只在一个中出现)
print(np.setxor1d(a, b))       # [1 2 6 7]

# 是否是子集
print(np.isin([1, 2, 3], a))   # [ True  True  True]

三、随机数生成 ​

1、新式 API(推荐) ​

python
rng = np.random.default_rng(seed=42)

# 均匀分布 [0, 1)
print(rng.random((2, 3)))

# 均匀分布 [low, high)
print(rng.uniform(0, 100, size=(2, 3)))

# 正态分布 N(μ, σ²)
print(rng.normal(loc=0, scale=1, size=(3, 3)))

# 标准正态分布
print(rng.standard_normal((3, 3)))

# 整数随机
print(rng.integers(0, 100, size=(2, 5)))

# 从数组中随机选择
choices = rng.choice([10, 20, 30, 40, 50], size=3, replace=False)
print(choices)  # 不重复抽样

# 随机排列
arr = np.arange(10)
rng.shuffle(arr)    # 原地打乱
print(arr)

# 生成排列副本(不修改原数组)
print(rng.permutation(np.arange(10)))

# 多项分布
print(rng.multinomial(10, [0.2, 0.3, 0.5]))

# 二项分布
print(rng.binomial(n=10, p=0.5, size=5))

# 泊松分布
print(rng.poisson(lam=5, size=5))

# Beta 分布
print(rng.beta(a=2, b=5, size=5))

2、旧式 API(兼容) ​

python
# 设置全局随机种子
np.random.seed(42)

# 均匀分布
print(np.random.rand(3, 3))        # [0, 1)
print(np.random.uniform(0, 10, 5)) # [0, 10)

# 正态分布
print(np.random.randn(3, 3))       # 标准正态
print(np.random.normal(0, 1, 5))   # N(0, 1)

# 整数
print(np.random.randint(0, 100, size=(2, 5)))

# 选择
print(np.random.choice([1, 2, 3, 4, 5], size=3, replace=False))

# 打乱
arr = np.arange(10)
np.random.shuffle(arr)              # 原地
print(np.random.permutation(10))    # 副本

推荐新式 API

default_rng() 创建独立的随机数生成器实例,避免全局状态污染,更适合并行计算和测试。旧式 API 仍可用但不推荐在新代码中使用。

四、文件 I/O ​

1、二进制格式(.npy / .npz) ​

python
a = np.array([[1, 2, 3], [4, 5, 6]])

# 保存单个数组
np.save("data.npy", a)

# 加载
loaded = np.load("data.npy")

# 保存多个数组到一个文件
b = np.array([10, 20, 30])
np.savez("data.npz", arr_a=a, arr_b=b)

# 加载
data = np.load("data.npz")
print(data["arr_a"])
print(data["arr_b"])

# 压缩保存
np.savez_compressed("data_compressed.npz", arr_a=a, arr_b=b)

2、文本格式(.csv / .txt) ​

python
a = np.array([[1, 2, 3],
              [4, 5, 6]])

# 保存为文本
np.savetxt("data.csv", a, delimiter=",", fmt="%d", header="c1,c2,c3")

# 加载文本
loaded = np.loadtxt("data.csv", delimiter=",", skiprows=1)

# 更灵活的加载(处理缺失值等)
loaded = np.genfromtxt("data.csv", delimiter=",", skip_header=1, filling_values=0)

3、格式对比 ​

格式优点缺点适用场景
.npy快速、无损、保留 dtype仅单个数组大数组持久化
.npz多数组打包、可压缩仅 NumPy 可读模型权重存储
.csv人类可读、跨语言慢、精度损失、无 dtype数据交换
.txt人类可读同 csv简单数据

更好的替代方案

对于大规模数据,推荐使用 HDF5(h5py)或 Parquet(pandas)格式,它们支持压缩、部分读取和跨语言兼容。

五、实用工具函数 ​

1、数组信息查看 ​

python
a = np.random.randn(3, 4, 5)

# 快速查看数组概要
print(np.info(a))

# 数组内存占用
print(a.nbytes)                # 480 bytes

# 判断数组类型
print(np.isscalar(3.14))      # True
print(np.isscalar(a))          # False

# 是否是数值类型
print(np.issubdtype(a.dtype, np.floating))  # True
print(np.issubdtype(a.dtype, np.integer))   # False

2、数组比较与近似 ​

python
a = np.array([1.0000001, 2.0000002])
b = np.array([1.0000002, 2.0000001])

# 近似相等(考虑浮点误差)
print(np.allclose(a, b))                 # True
print(np.allclose(a, b, atol=1e-8))     # True — 绝对误差容限
print(np.allclose(a, b, rtol=1e-7))     # True — 相对误差容限

# 逐元素近似比较
print(np.isclose(a, b))                  # [True True]

3、数组复制与组合 ​

python
a = np.array([1, 2, 3])

# 广播到更大形状
b = np.broadcast_to(a, (4, 3))
# [[1 2 3]
#  [1 2 3]
#  [1 2 3]
#  [1 2 3]]

# meshgrid: 生成网格坐标
x = np.array([1, 2, 3])
y = np.array([4, 5])
xx, yy = np.meshgrid(x, y)
print(xx)
# [[1 2 3]
#  [1 2 3]]
print(yy)
# [[4 4 4]
#  [5 5 5]]

# ogrid / mgrid: 懒惰求值网格
x, y = np.ogrid[0:3, 0:3]   # 返回开放网格(节省内存)
print(x.shape)  # (3, 1)
print(y.shape)  # (1, 3)

X, Y = np.mgrid[0:3, 0:3]   # 返回完整网格
print(X.shape)  # (3, 3)

4、nan 安全函数 ​

数据中经常包含缺失值(NaN),使用 nan 前缀函数可以在忽略 NaN 的情况下计算:

python
a = np.array([1, 2, np.nan, 4, 5])

print(np.nanmean(a))     # 3.0       — 忽略 NaN 的均值
print(np.nansum(a))      # 12.0      — 忽略 NaN 的求和
print(np.nanstd(a))      # 1.414...  — 忽略 NaN 的标准差
print(np.nanmin(a))      # 1.0       — 忽略 NaN 的最小值
print(np.nanmax(a))      # 5.0       — 忽略 NaN 的最大值
print(np.nanmedian(a))   # 3.0       — 忽略 NaN 的中位数
print(np.nanvar(a))      # 2.0       — 忽略 NaN 的方差

# 替换 NaN
b = np.nan_to_num(a, nan=0.0)
print(b)                 # [1. 2. 0. 4. 5.]

# 判断 NaN
print(np.isnan(a))       # [False False  True False False]

📖 官方文档