我在 Python 代码中有一个双 for 循环。我想提高执行速度,但矩阵是使用前一行和前一列的数据构建的。我该如何实现?
import numpy as np
num_rows, num_cols = 100, 5
matrix = np.zeros((num_rows, num_cols))
matrix[0, :] = np.random.rand(num_cols)
matrix[:, 0] = np.random.rand(num_rows)
coeff1 = np.random.rand(num_rows)
coeff2 = np.random.rand(num_rows)
coeff3 = np.random.rand(num_rows)
result = np.zeros_like(matrix)
for j in range(1, num_cols):
for n in range(1, num_rows):
term1 = coeff1[n] * matrix[n-1, j-1]
term2 = coeff2[n] * matrix[n, j-1]
term3 = coeff3[n] * matrix[n-1, j]
result[n, j] = term1 + term2 + term3
最佳答案
4
使其完全矢量化:
# Vectorized calculation for each j > 0
# Prev row, prev col (term1)
term1 = coeff1[1:, None] * matrix[:-1, :-1]
# Current row, prev col (term2)
term2 = coeff2[1:, None] * matrix[1:, :-1]
# Prev row, current col (term3)
term3 = coeff3[1:, None] * matrix[:-1, 1:]
# Summing the terms to get the result matrix (vectorized)
result[1:, 1:] = term1 + term2 + term3
|
使用 NumPy 的矢量化操作如下:
for j in range(1, num_cols):
term1 = coeff1[1:] * matrix[:-1, j-1]
term2 = coeff2[1:] * matrix[1:, j-1]
term3 = coeff3[1:] * matrix[:-1, j]
result[1:, j] = term1 + term2 + term3
在我的系统上这大约快了 12 倍。
2
-
我尝试了这个解决方案,但没有得到相同的结果。
– -
1我可以确认,在给定的代码中,
np.random.seed
结果是相同的。您是否执行了其他操作?另外,请查看@Soudipta-Dutta 的答案。这可能要好得多。
–
|
公平地说,让某些东西更快的想法与 C/C++ 非常相似。但你很幸运,因为你目前正在使用numpy
。我会选择。
根据文档。
支持 NumPy 的 Python 优化编译器。它使用 LLVM 编译器项目从 Python 语法生成机器代码。Numba 可以编译大量以数值为中心的 Python 子集,包括许多 NumPy 函数。此外,Numba 还支持循环的自动并行化、GPU 加速代码的生成以及 ufunc 和 C 回调的创建。
一个代码片段来指导您。
import numpy as np
from numba import jit
@jit(nopython=True, parallel=True)
def numba_func(matrix, coeff1, coeff2, coeff3, result, num_rows, num_cols):
for j in range(1, num_cols):
for n in range(1, num_rows):
term1 = coeff1[n] * matrix[n-1, j-1]
term2 = coeff2[n] * matrix[n, j-1]
term3 = coeff3[n] * matrix[n-1, j]
result[n, j] = term1 + term2 + term3
num_rows, num_cols = 100, 5
matrix = np.zeros((num_rows, num_cols))
matrix[0, :] = np.random.rand(num_cols)
matrix[:, 0] = np.random.rand(num_rows)
coeff1 = np.random.rand(num_rows)
coeff2 = np.random.rand(num_rows)
coeff3 = np.random.rand(num_rows)
result = np.zeros_like(matrix)
# Call the function with JIT-compiled speed
numba_func(matrix, coeff1, coeff2, coeff3, result, num_rows, num_cols)
如果您想要超快,您可以尝试使用并行计算来加快该过程。
你也可以使用 numba 中的矢量化函数
参见文档 ->
你可以做这样的事情
from numba import vectorize, int32, int64, float32, float64
import numpy as np
@vectorize([your inputs])
def f(x, y):
return x + y
|
你可以使用库来实现这一点
import numpy as np
# Example matrix dimensions
n = 1000
# Initialize matrices
matrix = np.zeros((n, n))
# Fill matrix using NumPy (vectorized operations)
for i in range(1, n):
matrix[i, 0] = matrix[i - 1, 0] + 1
for j in range(1, n):
matrix[i, j] = matrix[i - 1, j] + matrix[i, j - 1] - matrix[i - 1, j - 1]
2
-
OP 已经在使用 NymPy!
– -
这些不是矢量化操作。
–
|
|