如何不使用for循环高效实现numpy数组各元素与随机数相乘
数组逐元素乘随机数的高效实现方案
完全可以用numpy向量化运算替代双层Python循环,运算效率会有数量级的提升,且代码更简洁。
原实现用Python级别的双层循环遍历数组元素,存在大量解释器开销,对大数组的处理速度极慢。numpy的向量化操作会将运算下沉到C层面执行,同时自带的随机数生成接口可以直接生成和目标数组形状一致的随机矩阵,逐元素相乘即可实现相同逻辑。
优化后代码
import numpy as np A = np.array([[1,2,3],[3,4,5]]) B = np.ones_like(A) # 固定随机种子保证结果可复现 rng = np.random.default_rng(seed=0) # 直接生成形状和B一致、取值范围8~12的整数随机矩阵,逐元素相乘 B = B * rng.integers(low=8, high=13, size=B.shape)
注:numpy随机数生成器的
high参数为开区间,要取到上限12需要将high设为13。
效率对比
我们可以用1000*1000规模的数组做性能测试,直观感受差异:
import time import random import numpy as np # 生成测试用大数组 test_size = (1000, 1000) # 测试双层循环耗时 B1 = np.ones(test_size) start = time.time() for i in range(B1.shape[0]): for j in range(B1.shape[1]): B1[i][j] = B1[i][j] * random.randint(8, 12) print(f"双层循环耗时:{time.time() - start:.2f} s") # 测试向量化实现耗时 B2 = np.ones(test_size) rng = np.random.default_rng(seed=0) start = time.time() B2 = B2 * rng.integers(8, 13, size=test_size) print(f"向量化实现耗时:{time.time() - start:.4f} s")
测试结果中,双层循环通常需要数秒完成运算,而向量化实现耗时仅需零点几毫秒,性能差距可达数千倍。
如果需要完全对齐Python标准库random.seed(0)生成的随机数序列,可以先用列表推导式生成所有随机数再转numpy数组相乘,性能依然远高于双层循环:
import random import numpy as np A = np.array([[1,2,3],[3,4,5]]) B = np.ones_like(A) random.seed(0) # 先生成所有随机数再转换为numpy数组相乘 rand_arr = np.array([random.randint(8,12) for _ in range(B.size)]).reshape(B.shape) B = B * rand_arr
内容的提问来源于stack exchange,提问作者elenaby
相关产品推荐
相关产品推荐

