在 Python 数据分析、机器学习和科学计算领域,NumPy(Numerical Python)是不可或缺的基础库。它提供了高效的多维数组对象、便捷的数学运算函数,以及与其他科学计算库的无缝对接能力,解决了 Python 原生列表运算速度慢、多维数据处理繁琐的问题。本文将从核心概念出发,带大家掌握 NumPy 的关键用法,为后续数据分析和建模打下坚实基础。
一、NumPy 核心:ndarray 多维数组
NumPy 的核心是 ndarray(N-dimensional array),即多维数组。它与 Python 原生列表的本质区别在于:ndarray 是同构数据的集合(所有元素类型相同),支持向量化运算,运算速度远超列表;而列表可容纳不同类型数据,运算时需逐个元素循环,效率低下。
1. 创建 ndarray 数组
创建 ndarray 最常用的函数是 np.array(),传入列表或嵌套列表即可生成一维、二维或多维数组:
import numpy as np # 导入NumPy库,约定简写为np
# 1. 创建一维数组
arr1 = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr1) # 输出:[1 2 3 4 5]
# 2. 创建二维数组(嵌套列表)
arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("二维数组:\n", arr2)
除了手动传入数据,NumPy 还提供了快速创建特殊数组的函数,满足日常需求:
- •
np.zeros((3, 4)):创建 3 行 4 列的全 0 数组; - •
np.ones((2, 3)):创建 2 行 3 列的全 1 数组; - •
np.arange(0, 10, 2):创建从 0 到 10(不包含 10)、步长为 2 的一维数组([0, 2, 4, 6, 8]); - •
np.linspace(0, 1, 5):创建从 0 到 1、包含 5 个元素的均匀分布数组([0. , 0.25, 0.5 , 0.75, 1. ])。
2. ndarray 的关键属性
掌握数组的属性能帮助我们快速了解数据结构,常用属性如下:
print("数组维度:", arr2.ndim) # 输出:2(二维数组)
print("数组形状(行×列):", arr2.shape) # 输出:(3, 3)
print("数组元素个数:", arr2.size) # 输出:9
print("数组元素类型:", arr2.dtype) # 输出:int64(默认整数类型)
可通过 arr2.reshape((1, 9)) 修改数组形状(如将 3×3 数组转为 1×9 一维数组),但需保证修改前后元素总数一致;通过 arr1.astype(np.float64) 转换元素类型(如整数转浮点数)。
二、核心运算:向量化操作与广播机制
NumPy 最强大的特性之一是 向量化操作,无需循环即可对数组中所有元素执行运算,大幅提升效率。
1. 基本运算(加减乘除)
ndarray 支持与标量(单个数值)或同形状数组的直接运算,运算规则为“元素级运算”:
arr = np.array([1, 2, 3, 4])
# 1. 与标量运算(所有元素同时运算)
print("数组+2:", arr + 2) # 输出:[3 4 5 6]
print("数组×3:", arr * 3) # 输出:[3 6 9 12]
# 2. 同形状数组运算(对应元素两两运算)
arr_a = np.array([1, 2, 3])
arr_b = np.array([4, 5, 6])
print("数组相加:", arr_a + arr_b) # 输出:[5 7 9]
print("数组相乘:", arr_a * arr_b) # 输出:[4 10 18]
2. 广播机制(不同形状数组运算)
当两个数组形状不同时,NumPy 会通过“广播机制”自动扩展数组,使它们满足元素级运算条件。核心规则:维度较小的数组会在缺失的维度上重复扩展,直到与较大数组形状一致(前提是维度兼容)。
# 二维数组(3×2)与一维数组(2)运算
arr2 = np.array([[1, 2], [3, 4], [5, 6]])
arr1 = np.array([10, 20])
print("广播运算结果:\n", arr2 + arr1)
运算过程中,一维数组 arr1 会自动扩展为 [[10, 20], [10, 20], [10, 20]],再与 arr2 对应元素相加,输出:
[[11 22]
[13 24]
[15 26]]
3. 数学函数与统计运算
NumPy 内置了丰富的数学函数和统计函数,可直接作用于数组:
arr = np.array([1, 2, 3, 4, 5])
# 1. 数学函数(元素级)
print("平方根:", np.sqrt(arr)) # 输出:[1. 1.4142 1.732 2. 2.2361]
print("正弦值:", np.sin(arr)) # 计算每个元素的正弦(弧度制)
# 2. 统计运算(可指定维度)
print("总和:", arr.sum()) # 输出:15
print("均值:", arr.mean()) # 输出:3.0
print("最大值:", arr.max()) # 输出:5
print("最小值:", arr.min()) # 输出:1
# 二维数组按行/列统计(axis=0 按列,axis=1 按行)
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("按列求均值:", arr2.mean(axis=0)) # 输出:[2.5 3.5 4.5]
print("按行求最大值:", arr2.max(axis=1)) # 输出:[3 6]
三、数组索引与切片:数据筛选
NumPy 的索引和切片功能灵活高效,支持一维、多维数组的精准数据提取。
1. 一维数组索引与切片
与 Python 列表类似,一维 ndarray 支持通过位置索引(从 0 开始)、切片(start:end:step)获取数据:
arr = np.arange(10) # [0,1,2,3,4,5,6,7,8,9]
print("索引为3的元素:", arr[3]) # 输出:3
print("切片(2到7,步长2):", arr[2:7:2]) # 输出:[2 4 6]
print("反向切片(最后3个元素):", arr[-3:]) # 输出:[7 8 9]
2. 二维数组索引与切片
二维数组的索引格式为 arr[行索引/切片, 列索引/切片],用逗号分隔行和列:
arr2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 1. 提取单个元素(第2行第3列,索引从0开始)
print("单个元素:", arr2[1, 2]) # 输出:6
# 2. 提取整行/整列
print("第2行:", arr2[1]) # 输出:[4 5 6]
print("第3列:", arr2[:, 2]) # 输出:[3 6 9](: 表示所有行)
# 3. 切片提取子数组(第1-2行,第1-2列)
print("子数组:\n", arr2[0:2, 0:2])
输出的子数组为:
[[1 2]
[4 5]]
3. 布尔索引(条件筛选)
通过布尔表达式生成布尔数组,可快速筛选满足条件的元素:
arr = np.array([10, 20, 30, 40, 50])
# 生成布尔数组(元素>30为True,否则为False)
bool_arr = arr > 30
print("布尔数组:", bool_arr) # 输出:[False False False True True]
# 筛选满足条件的元素
print("筛选结果:", arr[bool_arr]) # 输出:[40 50]
# 简化写法(直接在索引中写条件)
print("简化筛选:", arr[arr > 30]) # 输出:[40 50]
四、总结与进阶方向
本文介绍了 NumPy 的核心知识点:ndarray 多维数组的创建与属性、向量化运算与广播机制、数组索引与切片,以及常用的数学和统计函数。这些内容是 NumPy 的基础,掌握后能轻松应对大部分数值计算场景,且为后续学习 Pandas(基于 NumPy 构建)、Matplotlib 等库提供支持。
若想进一步深入,可探索以下进阶方向:
- 1. 数组操作:学习
np.concatenate()(数组拼接)、np.split()(数组分割)、np.transpose()(数组转置)等高级操作; - 2. 线性代数:NumPy 的
np.linalg 模块提供矩阵乘法、求逆、特征值计算等线性代数功能,适用于机器学习中的矩阵运算; - 3. 随机数生成:
np.random 模块可生成各种分布的随机数(如正态分布、均匀分布),用于模拟实验和模型训练; - 4. 性能优化:了解 NumPy 的内存布局、避免循环使用向量化操作、利用
numba 加速运算等技巧。
NumPy 的学习核心是“摆脱 Python 列表的循环思维,拥抱向量化运算”。建议通过实际案例练习(如数值计算、数据预处理),逐步熟悉其 API 设计逻辑,你会发现数值计算变得高效且简洁。