为何我的Numpy数组操作比Python列表操作慢?
问题分析与解决
你遇到的核心问题是没有用对Numpy的正确用法,Numpy的优势在于向量化操作,而非用Python循环逐个操作数组元素,或是频繁扩容数组。
你的代码里的问题点:
- rw2的
np.append操作:Numpy数组是固定长度的,每次np.append都会创建新数组、复制原数据再添加新元素。这种频繁的内存分配与复制,比Python列表的append(列表内部预分配空间,仅在空间不足时扩容)慢得多,这就是rw2耗时是列表2-30倍的原因。 - rw3的Python循环赋值:虽然提前分配了数组空间,但仍用Python的
for循环逐个计算元素,Python循环本身有不小开销,完全没发挥Numpy的向量化计算优势,所以速度和列表相比没提升甚至更慢。
正确的Numpy实现方式
直接一次性生成所有随机步长,再用Numpy的cumsum(累加和)函数计算随机游走,全程都是向量化操作,没有Python循环,速度会比列表快很多:
from random import random import numpy as np import time t0 = time.time() # 原列表实现 rw1 = list() rw1.append(-1 if random() < 0.5 else 1) for i in range(1, 10000): movement = -1 if random() < 0.5 else 1 rw1.append(rw1[i-1] + movement) t1 = time.time() # 正确的Numpy向量化实现 # 一次性生成所有步长:50%概率-1,50%概率1 steps = np.random.choice([-1, 1], size=10000) rw_np = np.cumsum(steps) t2 = time.time() print("列表耗时:", t1-t0) print("Numpy向量化耗时:", t2-t1)
为什么这个实现更快?
np.random.choice直接在底层生成所有随机步长,不需要Python循环调用random()。np.cumsum是Numpy内置的向量化函数,用C语言实现,比Python循环累加快几个数量级。
你可以运行这段代码对比,会发现Numpy版本的耗时远低于列表实现。
内容的提问来源于stack exchange,提问作者katle
相关产品推荐
相关产品推荐

