如何提高python中矩阵乘法的效率?

时间:2018-05-10 13:28:03

标签: python python-3.x list numpy

我编写了一个代码来进行不同范围的矩阵乘法,但是执行代码需要花费很多时间,

代码:

使用嵌套循环

乘以两个矩阵的程序
import time

print("Enter the size of matrix A")
m = int(input())
n = int(input())
print("Enter the size of matrix A")
p = int(input())
q = int(input())
if(n==p):
     print('enter matrix A')
else:
    print("invalid entry")
    exit()
our_list1 = []
A = []
i = 0
int(i)

for i in range(m):
    for i in range(n):
            number = int(input('Please enter a element '))
            our_list1.append(number)
    A.append(our_list1)
    our_list1= []
print(A)
print('enter matrix B')
our_list1 = []
B = []

for i in range(p):
    for i in range(q):
            number = int(input('Please enter a element '))
            our_list1.append(number)
    B.append(our_list1)
    our_list1= []
print(B)
start_time = time.time()

#
our_list1 = []
R = []

for i in range(m):
    for i in range(q):
            number = 0
            our_list1.append(number)
    R.append(our_list1)
    our_list1= []
print(R)
for i in range(len(A)):

    # iterating by coloum by B
    for j in range(len(B[0])):

        # iterating by rows of B
        for k in range(len(B)):
            R[i][j] += A[i][k] * B[k][j]
print(R)
print("--- %s seconds ---" % (time.time() - start_time))

执行这种矩阵乘法方法需要更多时间,如何选择大尺寸范围矩阵乘法的有效方法?因此,更高维度的阵列可以平稳快速地执行。 样本输出:

Matrix A[[3, 3, 3], [3, 3, 3], [3, 3, 3]]
Matrix B[[3, 3, 3], [3, 3, 3], [3, 3, 3]]
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[27, 27, 27], [27, 27, 27], [27, 27, 27]]
--- 0.00014400482177734375 seconds ---

我需要0.00014400482177734375秒我可以在更高维度乘法时改进这个时间吗?

1 个答案:

答案 0 :(得分:3)

评论中的这个时间安排有一些明显的缺点:

  1. print()比较贵,与计算无关。将它包括在时间中可占据整个时间的很大一部分。
  2. 使用wallclock(time.time())不是获得稳定时间的好方法;你得到一次运行,你的系统上可能发生任何事情。
  3. 这应该为比较提供更好的测试用例:

    import numpy as np
    
    def python_lists():
        A = [[3, 3, 3], [3, 3, 3], [3, 3, 3]]
        B = [[3, 3, 3], [3, 3, 3], [3, 3, 3]]
        our_list1 = []
        R = []
    
        for i in range(3):
            for i in range(3):
                    number = 0
                    our_list1.append(number)
            R.append(our_list1)
            our_list1= []
    
        for i in range(len(A)):
    
            # iterating by coloum by B
            for j in range(len(B[0])):
    
                # iterating by rows of B
                for k in range(len(B)):
                    R[i][j] += A[i][k] * B[k][j]
    
    
    def numpy_array():
        A = np.full((3, 3), 3)
        B = np.full((3, 3), 3)
        result = np.dot(A, B)
    

    时间安排:

    %timeit python_lists()
    15 µs ± 45.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    %timeit numpy_array()
    5.57 µs ± 44.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    

    因此,对于这个例子,NumPy快了约3倍。但是如果你有更大的阵列,这将更加重要。

    编辑: 实际上,您可能会认为在函数内部创建AB对于实际矩阵乘法的计时没有帮助,所以如果我先创建列表/数组并传递它们,那么新的计时是:

    %timeit python_lists(A, B)
    14.4 µs ± 98.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    
    %timeit numpy_array(A, B)
    1.2 µs ± 13.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    并且,为了完整起见,对于具有形状(200,200)的数组:

    %timeit python_lists()
    6.99 s ± 128 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    %timeit numpy_array()
    5.77 ms ± 43.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)