3 sätt att multiplicera matriser i Python

I den här handledningen får du lära dig hur du multiplicerar två matriser i Python.

Du börjar med att lära dig villkoret för giltig matrismultiplikation och skriver en anpassad Python-funktion för att multiplicera matriser. Därefter kommer du att se hur du kan uppnå samma resultat med hjälp av kapslade listförståelser.

Slutligen fortsätter du att använda NumPy och dess inbyggda funktioner för att utföra matrismultiplikation mer effektivt.

Hur man kontrollerar om matrismultiplikation är giltig

Innan du skriver Python-kod för matrismultiplikation, låt oss återgå till grunderna för matrismultiplikation.

Matrismultiplikation mellan två matriser A och B är endast giltig om antalet kolumner i matris A är lika med antalet rader i matris B.

Du skulle förmodligen ha stött på detta tillstånd för matrismultiplikation tidigare. Men har du någonsin undrat varför det är så?

Tja, det är på grund av hur matrismultiplikation fungerar. Ta en titt på bilden nedan.

I vårt generiska exempel har matris A m rader och n kolumner. Och matris B har n rader och p kolumner.

Vad är formen på produktmatrisen?

Elementet vid index (i, j) i den resulterande matrisen C är punktprodukten av raden i i matrisen A och kolumn j i matrisen B.

Så för att få ett element vid ett visst index i den resulterande matrisen C, måste du beräkna punktprodukten för motsvarande rad och kolumn i matriserna A respektive B.

Genom att upprepa processen ovan får du produktmatrisen C med formen mxp—med m rader och p-kolumner, som visas nedan.

Och prickprodukten eller den inre produkten mellan två vektorer a och b ges av följande ekvation.

Låt oss sammanfatta nu:

  • Det är uppenbart att prickprodukten endast definieras mellan vektorer av samma längd.
  • Så för att punktprodukten mellan en rad och en kolumn ska vara giltig – när du multiplicerar två matriser – behöver du att båda har samma antal element.
  • I ovanstående generiska exempel har varje rad i matris A n element. Och varje kolumn i matris B har också n element.

Om du tittar närmare så är n antalet kolumner i matris A, och det är också antalet rader i matris B. Och det är just därför du behöver att antalet kolumner i matris A är lika med antalet rader i matris B.

Jag hoppas att du förstår villkoret för att matrismultiplikation ska vara giltig och hur man får fram varje element i produktmatrisen.

Låt oss fortsätta att skriva lite Python-kod för att multiplicera två matriser.

Skriv en anpassad Python-funktion för att multiplicera matriser

Som ett första steg, låt oss skriva en anpassad funktion för att multiplicera matriser.

Denna funktion bör göra följande:

  • Acceptera två matriser, A och B, som indata.
  • Kontrollera om matrismultiplikation mellan A och B är giltig.
  • Om giltigt, multiplicera de två matriserna A och B och returnera produktmatrisen C.
  • Annars, returnera ett felmeddelande om att matriserna A och B inte kan multipliceras.

Steg 1: Generera två matriser med heltal med hjälp av NumPys funktion random.randint(). Du kan också deklarera matriser som kapslade Python-listor.

import numpy as np
np.random.seed(27)
A = np.random.randint(1,10,size = (3,3))
B = np.random.randint(1,10,size = (3,2))
print(f"Matrix A:n {A}n")
print(f"Matrix B:n {B}n")

# Output
Matrix A:
 [[4 9 9]
 [9 1 6]
 [9 2 3]]

Matrix B:
 [[2 2]
 [5 7]
 [4 4]]

Steg 2: Fortsätt och definiera funktionen multiplicera_matris(A,B). Denna funktion tar in två matriser A och B som indata och returnerar produktmatrisen C om matrismultiplikationen är giltig.

def multiply_matrix(A,B):
  global C
  if  A.shape[1] == B.shape[0]:
    C = np.zeros((A.shape[0],B.shape[1]),dtype = int)
    for row in range(rows): 
        for col in range(cols):
            for elt in range(len(B)):
              C[row, col] += A[row, elt] * B[elt, col]
    return C
  else:
    return "Sorry, cannot multiply A and B."

Analysera funktionsdefinitionen

Låt oss gå vidare med att analysera funktionsdefinitionen.

Deklarera C som en global variabel: Som standard har alla variabler i en Python-funktion lokalt omfång. Och du kan inte komma åt dem utanför funktionen. För att göra produktmatrisen C tillgänglig utifrån, måste vi deklarera den som en global variabel. Lägg bara till det globala kvalet före variabelnamnet.

Kontrollera om matrismultiplikation är giltig: Använd formattributet för att kontrollera om A och B kan multipliceras. För valfri array arr, arr.shape[0] och arr.form[1] ange antalet rader respektive kolumner. Så om A.form[1] == B.form[0] kontrollerar om matrismultiplikation är giltig. Endast om detta villkor är sant kommer produktmatrisen att beräknas. Annars returnerar funktionen ett felmeddelande.

Använd kapslade loopar för att beräkna värden: För att beräkna elementen i den resulterande matrisen måste vi gå igenom raderna i matris A, och den yttre för loopen gör detta. Den inre for-loopen hjälper oss att gå igenom kolumnen i matris B. Och den innersta for-loopen hjälper oss att komma åt varje element i den valda kolumnen.

▶️ Nu när vi har lärt oss hur Python-funktionen för att multiplicera matriser fungerar, låt oss kalla funktionen med matriserna A och B som vi genererade tidigare.

multiply_matrix(A,B)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Eftersom matrismultiplikation mellan A och B är giltig returnerar funktionen multiplicera_matrix() produktmatrisen C.

Använd Python kapslad listförståelse för att multiplicera matriser

I föregående avsnitt skrev du en Python-funktion för att multiplicera matriser. Nu kommer du att se hur du kan använda kapslade listförståelser för att göra detsamma.

Här är den kapslade listförståelsen för att multiplicera matriser.

Till en början kan det här se komplicerat ut. Men vi kommer att analysera den kapslade listförståelsen steg för steg.

Låt oss fokusera på en listförståelse åt gången och identifiera vad den gör.

Vi använder följande allmänna mall för att förstå listan:

[<do-this> for <item> in <iterable>]

where,
<do-this>: what you'd like to do—expression or operation
<item>: each item you'd like to perform the operation on
<iterable>: the iterable (list, tuple, etc.) that you're looping through

▶️ Kolla in vår guide Listförståelse i Python – med exempel för att få en djupgående förståelse.

Innan du går vidare, observera att vi skulle vilja bygga den resulterande matrisen C en rad i taget.

Kapslad listaförståelse förklaras

Steg 1: Beräkna ett enda värde i matrisen C

Givet rad i i matris A och kolumn j i matris B, ger uttrycket nedan posten vid index (i, j) i matris C.

sum(a*b for a,b in zip(A_row, B_col)

# zip(A_row, B_col) returns an iterator of tuples
# If A_row = [a1, a2, a3] & B_col = [b1, b2, b3]
# zip(A_row, B_col) returns (a1, b1), (a2, b2), and so on

Om i = j = 1 kommer uttrycket att returnera posten c_11 i matrisen C. Så du kan få ett element i en rad på detta sätt.

Steg 2: Bygg en rad i matrisen C

Vårt nästa mål är att bygga en hel rad.

För rad 1 i matris A måste du gå igenom alla kolumner i matris B för att få en komplett rad i matris C.

Gå tillbaka till mallen för listförståelse.

  • Ersätt med uttrycket från steg 1, för det är vad du vill göra.
  • Ersätt sedan med B_col—varje kolumn i matris B.
  • Slutligen, ersätt med zip(*B)—listan som innehåller alla kolumner i matris B.

Och här är den första listförståelsen.

[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 

# zip(*B): * is the unzipping operator
# zip(*B) returns a list of columns in matrix B

Steg 3: Bygg alla rader och skaffa matrisen C

Därefter måste du fylla i produktmatrisen C genom att beräkna resten av raderna.

Och för detta måste du gå igenom alla rader i matris A.

Gå tillbaka till listförståelsen igen och gör följande.

  • Ersätt med listförståelsen från steg 2. Kom ihåg att vi beräknade en hel rad i föregående steg.
  • Ersätt nu med A_row—varje rad i matris A.
  • Och din är själva matrisen A, när du går genom dess rader.

Och här är vår sista förståelse av kapslade listor.🎊

[[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A]

Det är dags att verifiera resultatet! ✔

# cast into <a href="https://adminvista.com.com/numpy-reshape-arrays-in-python/">NumPy array</a> using np.array()
C = np.array([[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A])

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Om du tar en närmare titt, motsvarar detta den kapslade för slingor vi hade tidigare – bara att det är mer kortfattat.

Du kan också göra detta desto mer effektivt med hjälp av vissa inbyggda funktioner. Låt oss lära oss om dem i nästa avsnitt.

Använd NumPy matmul() för att multiplicera matriser i Python

np.matmul() tar in två matriser som indata och returnerar produkten om matrismultiplikationen mellan inmatningsmatriserna är giltig.

C = np.matmul(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Lägg märke till hur den här metoden är enklare än de två metoderna vi lärde oss tidigare. I själva verket, istället för np.matmul(), kan du använda en motsvarande @-operator, och vi kommer att se det direkt.

Hur man använder @ Operator i Python för att multiplicera matriser

I Python är @ en binär operator som används för matrismultiplikation.

Den arbetar på två matriser, och i allmänhet N-dimensionella NumPy-matriser, och returnerar produktmatrisen.

Obs: Du måste ha Python 3.5 och senare för att använda @-operatorn.

Så här kan du använda den.

C = [email protected]
print(C)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Lägg märke till att produktmatrisen C är densamma som den vi fick tidigare.

Kan du använda np.dot() för att multiplicera matriser?

Om du någonsin har stött på kod som använder np.dot() för att multiplicera två matriser, så här fungerar det.

C = np.dot(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Du kommer att se att np.dot(A, B) också returnerar den förväntade produktmatrisen.

Emellertid enligt NumPy-dokumentbör du endast använda np.dot() för att beräkna punktprodukten av två endimensionella vektorer och inte för matrismultiplikation.

Kom ihåg från föregående avsnitt, elementet vid index (i, j) av produktmatrisen C är punktprodukten av raden i i matris A och kolumnen j i matris B.

Eftersom NumPy implicit sänder denna punktproduktoperation till alla rader och alla kolumner, får du den resulterande produktmatrisen. Men för att hålla din kod läsbar och undvika oklarheter, använd np.matmul() eller @-operatorn istället.

Slutsats

🎯 I den här handledningen har du lärt dig följande.

  • Villkor för att matrismultiplikation ska vara giltig: antal kolumner i matris A = antal rader i matris B.
  • Hur man skriver en anpassad Python-funktion som kontrollerar om matrismultiplikation är giltig och returnerar produktmatrisen. Funktionens kropp använder kapslade för loopar.
  • Därefter lärde du dig hur du använder kapslade listförståelser för att multiplicera matriser. De är mer kortfattade än för loopar men är benägna att läsbarhetsproblem.
  • Slutligen har du lärt dig att använda NumPy inbyggda funktion np.matmul() för att multiplicera matriser och hur detta är det mest effektiva sett till hastighet.
  • Du lärde dig också om @-operatorn för att multiplicera två matriser i Python.

Och det avslutar vår diskussion om matrismultiplikation i Python. Som ett nästa steg, lär dig hur du kontrollerar om ett tal är primtal i Python. Eller lös intressanta problem på Python-strängar.

Lycka till med lärandet!🎉