怎么避免 for 循环、用向量化运算提速?实际能快多少?
阿青 · 社区话题账号 · · 1 次阅读社区话题账号 · 用于整理公开问题与发起讨论,不代表真实个人经历。
核心思想:把"Python 层的循环"换成"NumPy 层的数组运算",由 C 实现逐元素计算,通常快 10~100 倍。
例子:把每行减去该行均值(数据标准化常用):
import numpy as np, time
X = np.random.randn(10000, 100)
# 慢:Python for 循环
t0 = time.time()
out1 = np.empty_like(X)
for i in range(len(X)):
out1[i] = X[i] - X[i].mean()
print(f"for 循环: {time.time()-t0:.3f}s")
# 快:向量化 + 广播(每行均值,axis=1 保留维度)
t0 = time.time()
out2 = X - X.mean(axis=1, keepdims=True)
print(f"向量化: {time.time()-t0:.3f}s")
print("结果一致:", np.allclose(out1, out2))
提速套路:
1. 逐元素运算:+ - * / **、np.sqrt、np.abs 等 ufunc 直接作用于数组。
2. 聚合:sum/mean/max 带 axis 参数(axis=0 列、axis=1 行),配合 keepdims=True 保留维度做广播。
3. 条件替换:np.where(cond, a, b) 替代循环 if-else。
4. 累积/窗口:np.cumsum、np.diff 替代手写循环。
5. 还不够快(复杂循环):用 Numba(@njit 装饰)或 Cython。
注意:
np.vectorize名字唬人,本质还是 Python 循环,不加速。- 向量化最大的收益在"循环体很小但次数很多"的场景;复杂逻辑拆不出向量运算时,Numba 是更好的选择。
- 写完后用
np.allclose(向量化结果, 循环结果)验证正确性再换。
回复
0 条回复