我知道您想要一个列向量b = A * x,其中b[i] = (A[i, :] * x[i]).sum(),其中x 也是一个列向量。您实际上并不需要循环,因为 numpy 可以在没有循环的情况下更快地为您完成此操作。
A = np.array([[1,0,0],[0,1,0],[0,0,1]])
x = np.array([[1], [2], [3]])
b = (A * x).sum(axis=1, keepdims=True)
# b = array([[1],
# [2],
# [3]])
或者,您可以在计算之前简化您的问题:
(A[i, :] * x[i]).sum() 与 A[i, :].sum() * x[i] 相同,因此您可以对 A 的行求和 first,然后乘以 x 得到相同的结果。
b = A.sum(axis=1, keepdims=True) * x
但是,由于您必须有两个循环,(请注意,这会慢得多,尤其是对于较大的数组)
y = np.zeros(x.shape)
for i in range(A.shape[0]): # iterate over rows
for j in range(A.shape[1]): # iterate over columns
y[i, 0] = y[i, 0] + x[i, 0] * A[i,j] # Keep adding x[i] * A[i, j] to y[i]
# y = array([[1.],
# [2.],
# [3.]])
速度对比:
import timeit
from matplotlib import pyplot as plt
sizes = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000]
def mult1(A, x):
return (A * x).sum(axis=1, keepdims=True)
def mult2(A, x):
return A.sum(axis=1, keepdims=True) * x
def mult3(A, x):
y = np.zeros(x.shape)
for i in range(A.shape[0]): # iterate over rows
for j in range(A.shape[1]): # iterate over columns
y[i, 0] = y[i, 0] + x[i, 0] * A[i,j] # Keep adding x[i] * A[i, j] to y[i]
return y
time_vals = np.zeros((len(size),3))
for i, size in enumerate(sizes):
reps = 10 if size < 1000 else 1
print(sizes, reps)
A = np.random.random((size, size))
x = np.random.random((size, 1))
time_vals[i, 0] = timeit.timeit("mult1(A, x)", setup="from __main__ import A, x, mult1", number=reps) / reps
time_vals[i, 1] = timeit.timeit("mult2(A, x)", setup="from __main__ import A, x, mult2", number=reps) / reps
time_vals[i, 2] = timeit.timeit("mult3(A, x)", setup="from __main__ import A, x, mult3", number=reps) / reps
plt.plot(sizes, time_vals[:, 0], label="mult1")
plt.plot(sizes, time_vals[:, 1], label="mult2")
plt.plot(sizes, time_vals[:, 2], label="mult3")
给出这个情节。对于显着大小的数组,迭代方法始终比矢量化方法慢 1+ 个数量级。