NumPy 入门指南
NumPy 是 Python 数据科学生态的基础库,本文覆盖安装、核心概念、常用操作与实用技巧。
1. 什么是 NumPy
NumPy 是一个 Python 数据科学库,提供了一个强大的 N 维数组对象和各种工具来处理这些数组。NumPy 是 Python 科学计算的基础库之一,广泛用于数据分析、机器学习、图像处理等领域。
2. NumPy 的特点
| 特点 | 说明 |
|---|---|
| 高性能 | 使用 C 和 Fortran 编写,提供高效的数组操作和计算性能 |
| 多维数组 | 提供强大的 N 维数组对象,可处理各种维度的数据 |
| 广播机制 | 支持不同形状数组之间的运算,简化代码编写 |
| 丰富的函数库 | 包含大量数学、线性代数、统计函数,方便数据处理和分析 |
| 兼容性强 | 与 Pandas、Matplotlib、Scikit-learn 等科学计算库无缝集成 |
3. NumPy 的安装
方式一:pip 安装
pip install numpy
方式二:conda 安装
conda install numpy
4. NumPy 的基本使用
import numpy as np
# 创建一维数组
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr)) # <class 'numpy.ndarray'>
# 创建二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2d)
# 数组属性
print(arr.shape) # (5,)
print(arr2d.shape) # (2, 3)
print(arr.dtype) # int64
# 基本运算(向量化,无需循环)
print(arr + 10) # [11 12 13 14 15]
print(arr * 2) # [ 2 4 6 8 10]
# 切片
print(arr[1:4]) # [2 3 4]
print(arr2d[0, :]) # [1 2 3],获取第一行
4.1 数组的创建
NumPy 提供了多种方法来创建数组,包括从列表创建和使用函数生成。
# 从列表创建
arr = np.array([1, 2, 3, 4, 5])
# np.array vs np.asarray
# np.asarray 等价于 np.array(..., copy=False),仅在必要时才复制数据。
# 若输入已是 dtype 匹配的 ndarray,asarray 直接返回原对象(不复制);array 默认总是复制。
arr2 = np.asarray([1, 2, 3])
# 特殊数组
arr_zeros = np.zeros((3, 3)) # 全零数组,shape (3, 3)
arr_ones = np.ones((2, 4)) # 全一数组,shape (2, 4)
arr_empty = np.empty((2, 2)) # 未初始化数组,元素值不确定
arr_full = np.full((2, 3), 7) # 所有元素为 7
arr_random = np.random.rand(5) # 5 个 [0, 1) 随机数
# 与目标形状相同的特殊数组
arr_zeros_like = np.zeros_like(arr)
arr_ones_like = np.ones_like(arr)
# 序列数组
arr1 = np.arange(0, 10, 2) # [0 2 4 6 8],步长为 2
arr2 = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.],5 个等差元素
arr3 = np.logspace(0, 2, 5) # 从 10^0 到 10^2,5 个等比元素
⚠️ 注意
- NumPy 数组的元素类型必须相同,若创建时提供不同类型,会自动转换为公共类型。
- 数组大小一旦创建便固定,需改变大小时使用
reshape或创建新数组。- 运算会自动应用到整个数组(向量化),无需显式循环,代码更简洁且性能更高。
4.2 数组的属性
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # (2, 3) — 形状
print(arr.dtype) # int64 — 元素类型
print(arr.size) # 6 — 元素总数
print(arr.ndim) # 2 — 维度数
4.3 数组的操作
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 算术运算
print(arr1 + arr2) # [5 7 9]
print(arr1 * arr2) # [ 4 10 18]
# 统计函数(支持 axis 参数,见下方说明)
print(np.mean(arr1)) # 2.0
print(np.sum(arr2)) # 15
# 线性代数
arr3 = np.array([[1, 2], [3, 4]])
print(np.linalg.inv(arr3)) # 矩阵的逆
print(np.linalg.det(arr3)) # 矩阵的行列式(-2.0)
reshape / flatten / transpose
arr = np.arange(12).reshape(3, 4) # 变形为 3 行 4 列
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(arr.T) # 转置,shape 变为 (4, 3)
print(arr.flatten()) # 展平为一维: [0 1 2 ... 11]
axis 参数说明
axis 决定沿哪个维度进行运算,是统计函数中最常见的参数:
arr = np.array([[1, 2, 3],
[4, 5, 6]])
print(np.sum(arr)) # 21 — 对所有元素求和
print(np.sum(arr, axis=0)) # [5 7 9] — 沿列方向(逐列求和)
print(np.sum(arr, axis=1)) # [6 15] — 沿行方向(逐行求和)
np.mean、np.max、np.min、np.std等统计函数均支持axis参数,用法相同。
4.4 ndarray 的数据类型
NumPy 数组支持多种数据类型,可在创建时通过 dtype 参数指定。
| 数据类型 | 类型代码 | 说明 |
|---|---|---|
bool | bool | 布尔值,True 或 False |
int8 | i1 | 8 位带符号整数 |
uint8 | u1 | 8 位无符号整数 |
int16 | i2 | 16 位带符号整数 |
uint16 | u2 | 16 位无符号整数 |
int32 | i4 | 32 位带符号整数 |
uint32 | u4 | 32 位无符号整数 |
int64 | i8 | 64 位带符号整数(默认整数类型) |
uint64 | u8 | 64 位无符号整数 |
float16 | f2 | 16 位浮点数 |
float32 | f4 / f | 32 位浮点数 |
float64 | f8 / d | 64 位浮点数(默认浮点类型) |
complex64 | c8 | 由两个 32 位浮点数组成的复数 |
complex128 | c16 | 由两个 64 位浮点数组成的复数 |
object | O | Python 对象类型 |
string_ | S | 字节字符串类型 |
unicode_ | U | Unicode 字符串类型 |
4.5 数组的索引和切片
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 基本索引
print(arr[0, 1]) # 2 — 第一行第二列
# 切片
print(arr[1:3, :]) # 第二、三行的所有列
print(arr[:, 0:2]) # 所有行的前两列
# 布尔索引
print(arr[arr > 5]) # [6 7 8 9] — 返回大于 5 的元素(副本)
4.6 广播机制(Broadcasting)
广播是 NumPy 最核心的特性之一,允许形状不同的数组之间直接进行运算,无需手动扩展维度。
广播规则:从尾部维度开始对齐,若两个维度相等,或其中一个为 1,则可广播;否则报错。
a = np.array([[1, 2, 3],
[4, 5, 6]]) # shape (2, 3)
b = np.array([10, 20, 30]) # shape (3,) → 广播为 (2, 3)
print(a + b)
# [[11 22 33]
# [14 25 36]]
# 列向量广播
c = np.array([[1], [2]]) # shape (2, 1) → 广播为 (2, 3)
print(a * c)
# [[ 1 2 3]
# [ 8 10 12]]
4.7 常见陷阱:视图(View)vs 副本(Copy)
切片返回的是视图,不是副本,修改切片会直接影响原数组,这是初学者最常踩的坑。
arr = np.array([1, 2, 3, 4, 5])
slice_arr = arr[1:4] # 视图,非新数组
slice_arr[0] = 99
print(arr) # [ 1 99 3 4 5] ← 原数组被修改!
# 如需独立副本,使用 .copy()
slice_copy = arr[1:4].copy()
slice_copy[0] = 0
print(arr) # 原数组不受影响
布尔索引和花式索引(整数数组索引)返回的是副本,不会影响原数组。
5. 常用函数速查
数组创建
| 函数 | 说明 |
|---|---|
np.array() | 从列表/序列创建数组 |
np.asarray() | 创建数组(输入已是 ndarray 时不复制) |
np.zeros() | 创建全零数组 |
np.ones() | 创建全一数组 |
np.full() | 创建填充指定值的数组 |
np.empty() | 创建未初始化数组 |
np.zeros_like() | 创建与目标形状相同的全零数组 |
np.ones_like() | 创建与目标形状相同的全一数组 |
np.arange() | 创建等差数列(类似 range) |
np.linspace() | 创建等差数列(指定元素个数) |
np.logspace() | 创建等比数列 |
np.random.rand() | 生成 [0, 1) 均匀分布随机数组 |
数组变形
| 函数 | 说明 |
|---|---|
np.reshape() | 改变数组形状(不改变数据) |
np.flatten() | 展平为一维(返回副本) |
np.transpose() / .T | 转置数组 |
np.concatenate() | 沿指定轴连接多个数组 |
np.stack() | 沿新轴堆叠数组 |
np.split() | 分割数组 |
统计函数
| 函数 | 说明 |
|---|---|
np.sum() | 求和(支持 axis) |
np.mean() | 平均值(支持 axis) |
np.median() | 中位数 |
np.std() | 标准差(支持 axis) |
np.var() | 方差(支持 axis) |
np.max() / np.min() | 最大 / 最小值(支持 axis) |
np.argmax() / np.argmin() | 最大 / 最小值的索引 |
np.sort() | 排序 |
np.unique() | 返回唯一元素 |
数学函数
| 函数 | 说明 |
|---|---|
np.abs() | 绝对值 |
np.sqrt() | 平方根 |
np.exp() | 指数() |
np.log() | 自然对数 |
np.sin() / np.cos() / np.tan() | 三角函数 |
np.dot() | 点积 |
np.cross() | 叉积 |
线性代数
| 函数 | 说明 |
|---|---|
np.linalg.inv() | 矩阵求逆 |
np.linalg.det() | 矩阵行列式 |
np.linalg.eig() | 特征值与特征向量 |
np.linalg.solve() | 求解线性方程组 |
条件与查找
| 函数 | 说明 |
|---|---|
np.where() | 根据条件选择元素 |
np.append() | 追加元素(返回新数组) |
np.insert() | 插入元素(返回新数组) |
np.delete() | 删除元素(返回新数组) |