一、NumPy 是什么?
NumPy(Numerical Python)是 Python 最核心的科学计算库,专为处理多维数组设计。它提供:
- 高性能数组对象:ndarray
- 向量化运算能力:无需循环即可批量操作数据
- 数学函数宝库:线性代数、傅里叶变换、随机数生成等
- 跨语言接口:底层用C编写,速度媲美编译语言
为什么选择 NumPy?
- 速度优势:比纯Python列表快100倍以上
- 内存高效:连续内存存储,支持大数据处理
- 生态核心:Pandas、Matplotlib、Scikit-learn等库都基于NumPy
二、核心对象 ndarray
1. 数组创建大全
import numpy as np
# 从列表创建
a = np.array([1,2,3]) # 一维数组
b = np.array([[1,2],[3,4]]) # 二维数组
# 特殊数组生成
zeros = np.zeros((3,4)) # 3行4列全0矩阵
ones = np.ones((2,3,2)) # 三维全1数组(2个2x3矩阵)
identity = np.eye(5) # 5x5单位矩阵
random_arr = np.random.rand(2,5) # 2x5的随机数组(0-1均匀分布)
# 序列生成
range_arr = np.arange(0, 10, 2) # [0 2 4 6 8]
linspace_arr = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.]
2. 数组属性详解
arr = np.random.rand(3,4,5)
print("维度数量:", arr.ndim) # 3
print("形状:", arr.shape) # (3,4,5)
print("元素总数:", arr.size) # 3 * 4 * 5=60
print("数据类型:", arr.dtype) # float64
print("元素字节数:", arr.itemsize) # 8 bytes
print("内存布局:", arr.flags) # 查看存储方式
三、数组操作全攻略
1. 索引与切片
arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
# 基本索引
print(arr[1, 2]) # 6 → 第二行第三列
print(arr[:, 1]) # [2 5 8] → 所有行的第二列
# 布尔索引
mask = arr > 5
print(arr[mask]) # [6 7 8 9]
# 花式索引
print(arr[[0,2], 1]) # [2 8] → 第0和2行的第1列
2. 形状变换
arr = np.arange(12)
# 重塑形状(不改变数据)
reshaped = arr.reshape(3,4)
# 自动推导维度
auto_shape = arr.reshape(3,-1) # 3行,自动计算列数
# 展平操作
flattened = arr.flatten() # 返回拷贝
raveled = arr.ravel() # 返回视图
# 转置矩阵
transposed = reshaped.T
3. 向量化运算
a = np.array([1,2,3])
b = np.array([4,5,6])
# 逐元素运算
print(a + b) # [5 7 9]
print(a * 2) # [2 4 6]
print(np.sqrt(a)) # [1. 1.414 1.732]
# 矩阵乘法
matrix = np.array([[1,2],[3,4]])
print(matrix @ matrix) # 矩阵相乘 [[7 10],[15 22]]
4. 广播机制
# 不同形状数组运算
a = np.array([[1,2,3], [4,5,6]]) # shape (2,3)
b = np.array([10,20,30]) # shape (3,)
# b被广播为:
# [[10 20 30]
# [10 20 30]]
result = a + b # [[11 22 33], [14 25 36]]
四、进阶功能
1. 聚合计算
arr = np.random.rand(100, 50)
print("总计:", arr.sum())
print("列平均:", arr.mean(axis=0)) # 每列的平均值
print("行最大:", arr.max(axis=1)) # 每行的最大值
print("标准差:", arr.std())
print("中位数:", np.median(arr))
2. 线性代数
from numpy.linalg import inv, det
matrix = np.array([[1,2], [3,4]])
print("逆矩阵:\n", inv(matrix))
print("行列式:", det(matrix))
print("特征值:", np.linalg.eig(matrix)[0])
3. 文件操作
# 保存为二进制文件
np.save('data.npy', arr)
# 加载数据
loaded = np.load('data.npy')
# 文本文件操作
np.savetxt('matrix.csv', matrix, delimiter=',')
五、性能优化技巧
1. 避免循环
# 错误示范
result = []
for i in range(1000000):
result.append(i*2)
# NumPy优化版
arr = np.arange(1000000)
result = arr * 2 # 快100倍以上
2. 内存预分配
# 预先分配空间
output = np.empty_like(input_array)
np.multiply(input1, input2, out=output)
3. 视图 vs 副本
a = np.arange(10)
b = a[::2] # 视图(不复制数据)
c = a.copy() # 完整副本
六、实战应用场景
1. 图像处理
from PIL import Image
# 转换为NumPy数组
img = np.array(Image.open('photo.jpg'))
# 颜色通道处理
red_channel = img[:,:,0] # 提取红色通道
gray_scale = img.mean(axis=2) # 转换为灰度图
2. 数据预处理
# 标准化数据
data = np.random.normal(loc=10, scale=5, size=100)
normalized = (data - data.mean()) / data.std()
# 处理缺失值
data_with_nan = np.array([1, np.nan, 3, 4])
clean_data = np.nan_to_num(data_with_nan) # 用0替换nan
3. 信号处理
# 快速傅里叶变换
t = np.linspace(0, 1, 1000)
signal = np.sin(2*np.pi*5*t) + 0.5*np.random.randn(1000)
freq = np.fft.fft(signal)
七、常见问题解决方案
Q1: 如何处理形状不匹配?
- 使用
reshape
调整维度 - 检查广播规则是否满足:
- 从后向前比较维度
- 每个维度要么相等,要么其中一个是1
Q2: 如何提升计算速度?
- 尽量使用NumPy内置函数
- 避免在循环中操作数组
- 使用
a @ b
代替np.dot(a,b)
进行矩阵乘法
Q3: 如何调试数组形状?
print(arr.shape) # 查看维度
assert arr.ndim == 3, "需要三维数组"
np.testing.assert_array_equal(a, b) # 验证数组相等性
通过系统学习这些内容,你将能够:
- 高效处理百万级数据
- 进行复杂的数学运算
- 为机器学习准备数据
- 优化科学计算代码性能
建议结合Jupyter Notebook进行实践,通过%timeit
魔法命令比较不同方法的性能差异,加深对NumPy优势的理解。