Как я могу повысить эффективность умножения матриц в Python?

Я написал код для умножения матриц разного диапазона, но выполнение кода занимает много времени,

код:

Программа для умножения двух матриц с использованием вложенных циклов

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 секунд, могу ли я улучшить этот момент времени, когда я делаю это для более высокого умножения измерений?

Просто используйте для этого специализированный модуль, а именно numpy.

Sqoshu 10.05.2018 15:29

Я не думаю, что 0,0001 секунды - это «много времени», но вы должны использовать numpy, если вам нужно делать что-то с большими матрицами.

agubelu 10.05.2018 15:30

Хорошо, я никогда раньше не использовал numpy, могу ли я сделать с этим умножение матриц более высокого порядка?

user9168798 10.05.2018 15:31

Вы можете, этот модуль был разработан для эффективного решения подобных проблем.

Sqoshu 10.05.2018 15:32

ладно, сделаю с нимпи и проверю разницу во времени

user9168798 10.05.2018 15:34

импортировать numpy как np res = np.dot (A, B) print (res)

user9168798 10.05.2018 15:40

[[3, 3, 3], [3, 3, 3], [3, 3, 3]] [[3, 3, 3], [3, 3, 3], [3, 3, 3]] [[27 27 27] [27 27 27] [27 27 27]] --- 0,0005307197570800781 секунд ---

user9168798 10.05.2018 15:41

Мне потребовалось немного больше, чем явный метод цикла

user9168798 10.05.2018 15:42
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
8
183
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У этого тайминга в ваших комментариях есть существенные недостатки:

  1. print() сравнительно дорогой и не имеет никакого отношения к расчету. Включение его в тайминги может занять большую часть общего времени.
  2. Использование настенных часов (time.time()) - не лучший способ получить стабильное время; вы получаете один запуск, и в вашей системе может происходить что угодно.

Это должно дать лучший тестовый пример для сравнения:

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 раза быстрее. Но это было бы более важно, если бы у вас были массивы побольше.

Обновлено: И на самом деле вы можете возразить, что создание A и B внутри функции не помогает для определения времени фактического умножения матриц, поэтому, если я вместо этого сначала создаю списки / массивы и передаю их, новые сроки будут следующими:

%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)

И для полноты картины для массива с shape (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)

спасибо за подробный анализ, теперь я пытаюсь создать функцию, в которой я могу просто передать A и B

user9168798 10.05.2018 16:50

как вы рассчитали время функции% timeit python_lists (A, B) ?, если я использую это в коде или терминале, я получаю синтаксическую ошибку

user9168798 10.05.2018 17:06

@NikhilR Я использую Spyder в качестве своей IDE, поэтому он дает мне доступ к магическим методам iPython - %timeit - один из. Если вы используете обычный Python, вам придется перепрыгнуть через несколько препятствий с timeit модуль.

roganjosh 10.05.2018 17:10

Другие вопросы по теме