NumPy 数组常用函数手册:从入门到进阶

前言

NumPy(Numerical Python)是 Python 数据科学栈的基石。它的核心是 ndarray------一个高性能的多维数组对象,配合向量化运算,让数值计算比纯 Python 快数十倍甚至上百倍。Pandas、Matplotlib、Scikit-learn 等几乎所有数据科学库都建立在 NumPy 之上。

本文按使用频率梳理 NumPy 的核心函数,覆盖数组创建、索引切片、形状操作、数学运算、统计聚合等全链路,适合作为案头速查手册。

版本说明: 本文基于 NumPy 1.24+,部分旧版 API(如 np.int)已废弃,建议使用 np.int64 等明确类型。


一、数组创建

创建数组是使用 NumPy 的第一步,不同场景选不同函数可以少写很多代码。

1.1 从 Python 序列创建

python 复制代码
import numpy as np

# 从列表创建(最常用)
arr = np.array([1, 2, 3, 4, 5])

# 从嵌套列表创建二维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])

1.2 创建占位数组

当你知道形状但暂不确定数值时,用占位数组初始化:

python 复制代码
# 空数组(不初始化,内容是内存中的随机值,速度最快)
arr = np.empty((3, 4))

# 全零数组(最常用,适合作为累加器的起点)
arr = np.zeros((3, 4))

# 全一数组(适合作为乘法因子的起点)
arr = np.ones((3, 4))

# 填充指定值
arr = np.full((3, 4), 100)

# 单位矩阵(仅方阵,线性代数常用)
arr = np.eye(4, dtype=int)

# 创建与已有数组同形状的占位数组
arr = np.zeros_like(existing_arr)
arr = np.ones_like(existing_arr)

1.3 等差/等比数组

python 复制代码
# arange:指定起止 + 步长(类似 Python 内置 range)
np.arange(0, 10, 2)         # [0, 2, 4, 6, 8]

# linspace:指定起止 + 元素个数(适合生成 x 轴刻度)
np.linspace(0, 1, 5)        # [0, 0.25, 0.5, 0.75, 1]
np.linspace(0, 10, 100)     # 生成 100 个点用于绘图

# logspace:对数刻度(适合在对数坐标下均匀采样)
np.logspace(0, 3, 4)        # [1, 10, 100, 1000]

arange vs linspace arange 关心步长,linspace 关心点数。画图时几乎总是用 linspace,因为控制生成的点数更直观。


二、随机数生成

随机数是模拟、采样和数据增强的基础。NumPy 提供了丰富的随机函数。

python 复制代码
# 随机整数 [low, high) 范围
np.random.randint(0, 100, 10)     # 一维
np.random.randint(0, 100, (3, 4)) # 多维

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

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

# 指定范围的均匀分布
np.random.uniform(1, 10, (3, 5))

# 正态分布(自定义均值和标准差)
np.random.normal(loc=0, scale=1, size=(3, 5))

# 从给定数组中有放回/无放回随机抽取
np.random.choice([1, 2, 3, 4, 5], size=3, replace=True)

# 设置随机种子(确保每次运行结果一致,调试必备)
np.random.seed(42)

最佳实践: 每次用到随机数时养成随手写 np.random.seed() 的习惯,否则调试时结果变了你还以为代码出了问题。

新版随机数生成器(推荐)

python 复制代码
# NumPy 1.17+ 推荐使用 Generator API,线程更安全
rng = np.random.default_rng(seed=42)
rng.integers(0, 100, 10)
rng.random((3, 5))
rng.normal(0, 1, (3, 5))

三、数组属性

了解数组的元信息是调试和验证逻辑的基本功。

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

arr.shape      # (2, 3)  --- 形状
arr.dtype      # dtype('int64') --- 元素类型
arr.ndim       # 2 --- 维度数(几维数组)
arr.size       # 6 --- 元素总数
arr.itemsize   # 8 --- 单个元素的字节数(int64 = 8 bytes)
arr.nbytes     # 48 --- 总内存占用(size × itemsize)

四、索引与切片

这是日常操作中最频繁的部分,掌握好可以少写很多显式循环。

4.1 一维数组

python 复制代码
arr = np.arange(10)           # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

arr[0]                        # 0 --- 首元素
arr[-1]                       # 9 --- 末元素
arr[2:7]                      # [2, 3, 4, 5, 6] --- 切片(左闭右开)
arr[::2]                      # [0, 2, 4, 6, 8] --- 步长为 2
arr[::-1]                     # 反转数组

4.2 二维数组

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

arr2d[1, 2]        # 6 --- 第 2 行第 3 列
arr2d[0, :]        # [1, 2, 3] --- 第 1 行
arr2d[:, 1]        # [2, 5, 8] --- 第 2 列
arr2d[1:, 1:]      # [[5, 6], [8, 9]] --- 右下角子矩阵

4.3 花式索引与布尔索引

这是 NumPy 的"杀手级"特性,一次性替代大量循环:

python 复制代码
# 花式索引:按位置列表取值
arr = np.array([10, 20, 30, 40, 50])
arr[[0, 2, 4]]               # [10, 30, 50]

# 布尔索引:按条件过滤
arr[arr > 30]                # [40, 50]
arr[(arr > 15) & (arr < 45)] # [20, 30, 40]

# 注意:多个条件用 & / |,不能用 and / or,每个条件必须加括号
mask = (arr > 20) | (arr < 15)
arr[mask]

五、数组形状操作

模型输入常常要求特定形状,形状转换是数据预处理的日常操作。

python 复制代码
arr = np.arange(12).reshape(3, 4)
# [[0, 1, 2, 3],
#  [4, 5, 6, 7],
#  [8, 9, 10, 11]]

5.1 展平

python 复制代码
arr.flatten()     # 返回副本,修改不影响原数组
arr.ravel()       # 尽可能返回视图,修改会影响原数组(更快)
arr.reshape(-1)   # 等价于展平

flatten() vs ravel() ravel() 不复制数据,性能更好;flatten() 总是产生副本。如果不需要独立的副本,优先用 ravel()

5.2 转置与形状变换

python 复制代码
arr.T             # 矩阵转置
arr.reshape(2, 6) # 改变形状(元素总数必须一致)

# 使用 -1 让 NumPy 自动推断维度
arr.reshape(2, -1)   # 行数为 2,列数自动计算
arr.reshape(-1, 4)   # 列数为 4,行数自动计算

5.3 新增维度

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

arr[np.newaxis, :]    # shape (1, 4)
arr[:, np.newaxis]    # shape (4, 1)
arr.reshape(1, -1)    # 等价

5.4 拼接与分割

python 复制代码
# 拼接
np.concatenate([arr1, arr2], axis=0)   # 垂直拼接(沿着行方向堆)
np.concatenate([arr1, arr2], axis=1)   # 水平拼接
np.vstack([arr1, arr2])                # 垂直拼接的快捷方式
np.hstack([arr1, arr2])                # 水平拼接的快捷方式

# 分割
np.split(arr, 3, axis=0)               # 切成 3 等份
np.hsplit(arr, 2)                      # 水平方向切成 2 份

六、数学运算

NumPy 的一个核心优势是向量化运算------不用写 for 循环就能对整个数组做计算。

6.1 标量运算(广播)

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

arr + 1        # [2, 3, 4, 5, 6]
arr * 2        # [2, 4, 6, 8, 10]
arr ** 2       # [1, 4, 9, 16, 25]
arr / 2        # [0.5, 1., 1.5, 2., 2.5]
np.sqrt(arr)   # 逐元素开方
np.log(arr)    # 逐元素取对数
np.exp(arr)    # 逐元素指数

6.2 数组间运算

python 复制代码
arr1 + arr2    # 逐元素加法
arr1 * arr2    # 逐元素乘法(不是矩阵乘法!)

# 矩阵乘法(两种写法等价)
np.dot(arr1, arr2)
arr1 @ arr2

6.3 聚合函数

python 复制代码
np.sum(arr)         # 求和
np.prod(arr)        # 求积
np.mean(arr)        # 均值
np.median(arr)      # 中位数
np.std(arr)         # 标准差
np.var(arr)         # 方差
np.min(arr) / np.max(arr)         # 极值
np.argmin(arr) / np.argmax(arr)   # 极值索引

6.4 按轴聚合

这是 Pandas 的 groupby 在 NumPy 层的对应物:

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

np.sum(arr2d, axis=0)    # [5, 7, 9]  --- 对每一列求和(沿着行方向压缩)
np.sum(arr2d, axis=1)    # [6, 15]    --- 对每一行求和

axis 记忆口诀: axis=0 是沿着行的方向"压扁"(列不变),即对每列操作;axis=1 是沿着列的方向"压扁",即对每行操作。


七、排序与搜索

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

# 排序
np.sort(arr)                  # 返回排好序的新数组
arr.sort()                    # 原地排序(不产生副本)

# 获取排序后各元素的原始索引(得分排名等场景常用)
idx = np.argsort(arr)         # arr[idx] 就是排好序的结果

# 去重并排序
np.unique(arr)                        # [1, 2, 3, 4, 5, 6, 9]
np.unique(arr, return_counts=True)    # 同时返回各唯一值的出现次数

# 查找满足条件的索引
np.where(arr > 3)             # 返回元组 (array_of_indices,)
np.where(arr > 2, arr, 0)     # 三参数形式:满足条件保留,否则置 0

# 查找插入位置(二分查找,要求数组已排序)
np.searchsorted(np.sort(arr), 5)

八、逻辑操作

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

# 全局判断
np.any(arr > 3)         # True --- 是否存在满足条件的元素
np.all(arr > 0)         # True --- 是否全部满足条件

# 条件筛选与替换
np.where(arr > 2, arr, 0)       # >2 的保留,否则置 0

# 多条件(用列表传入)
conditions = [arr < 3, arr > 3]
choices = [arr * 2, arr * 3]
np.select(conditions, choices, default=0)

# 数值裁剪(去除异常值常用)
np.clip(arr, 2, 4)     # <2 的变 2,>4 的变 4

九、累计操作

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

np.cumsum(arr)      # [1, 3, 6, 10, 15]  --- 累计和(收益曲线常用)
np.cumprod(arr)     # [1, 2, 6, 24, 120] --- 累计积

# 沿指定轴
np.cumsum(arr2d, axis=0)   # 每列的逐行累计和

十、数据类型转换

python 复制代码
arr = np.array([1.5, 2.7, 3.9])

arr.astype(int)       # [1, 2, 3] --- 浮点转整型(向下取整)
arr.astype(str)       # ['1.5', '2.7', '3.9']

# 类型标识(推荐使用显式类型名)
np.int64(arr)
np.float32(arr)
np.bool_(arr)

精度与内存权衡: 如果数据量很大,把 float64 转为 float32 可以节省一半内存,对精度要求不高的场景非常实用。


十一、拷贝与视图

这是 NumPy 最容易踩的坑:不小心修改了视图,原数组也跟着变了。

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

# 深拷贝(独立副本,修改不影响原数组)
arr_copy = arr.copy()

# 浅拷贝 / 视图(与原数组共享底层内存)
arr_view = arr.view()

# 切片通常返回视图
sliced = arr[1:4]
sliced[0] = 999        # arr 也会被修改!

# 判断两个数组是否共享内存
np.shares_memory(arr, arr_view)      # True
np.shares_memory(arr, arr_copy)      # False
arr.base is None                     # True 表示是"基数组"

经验法则: 除非确定要节省内存,否则对切片结果做修改前先 .copy() 一下,能避免大量诡异的 bug。


十二、常用技巧速查

python 复制代码
# 计算两数组的欧氏距离
dist = np.sqrt(np.sum((arr1 - arr2) ** 2))

# 归一化到 [0, 1]
normalized = (arr - arr.min()) / (arr.max() - arr.min())

# Z-score 标准化
standardized = (arr - arr.mean()) / arr.std()

# 找出 Top-K 值的索引
top3_idx = np.argsort(arr)[-3:]

# 按频率排序(词频统计常用)
values, counts = np.unique(arr, return_counts=True)
sorted_idx = np.argsort(-counts)     # 降序

总结

NumPy 的核心功可以归纳为三件事:创建数组、操作数组形状、对数组做向量化计算。使用 NumPy 时牢记两条原则:

  1. 消除 for 循环------能用向量化运算就用向量化,这是性能提升的根本来源。
  2. 关注视图 vs 副本------弄清楚什么时候在操作原数据、什么时候在操作复制品,能避免 90% 的诡异 bug。

掌握了这些函数,你就有了用 Python 做数值计算的最底层工具箱。配合 Pandas 做数据处理、Matplotlib 做可视化,就是完整的数据分析三件套。

相关推荐
威尔逊·柏斯科·希伯理12 小时前
机器学习第一天(共12天)
人工智能·python·机器学习·conda·numpy·pandas·matplotlib
杭州的平湖秋月1 天前
Numpy 的基础索引、高级索引、布尔索引和 take_along_axis
python·numpy·高级索引
松☆2 天前
昇腾NPU的信号处理加速库,跟NumPy的FFT有啥区别?
numpy·信号处理
松☆2 天前
Triton推理服务接昇腾NPU,GE后端怎么搭?
华为·性能优化·numpy·信号处理·harmonyos
bloxed3 天前
【AI大模型--NumPy-06】随机数生成与蒙特卡洛模拟
人工智能·numpy
bloxed3 天前
【AI大模型--NumPy-05】统计分析实战指南
人工智能·numpy
心中有国也有家3 天前
MindSpore 适配 NPU 的全链路解析——从算子注册到端到端性能调优
人工智能·pytorch·python·学习·numpy
Cloud_Shy6184 天前
Python 数据分析基础入门:《Excel Python:飞速搞定数据分析与处理》学习笔记系列(第十二章 用户定义函数 下篇)
python·plotly·数据分析·excel·numpy·pandas
ujainu小4 天前
CANN asnumpy:在 NPU 上跑 NumPy 工作负载
numpy