3 måder at multiplicere matricer i Python

I denne øvelse lærer du, hvordan du multiplicerer to matricer i Python.

Du starter med at lære betingelsen for gyldig matrixmultiplikation og skrive en brugerdefineret Python-funktion til at multiplicere matricer. Dernæst vil du se, hvordan du kan opnå det samme resultat ved hjælp af indlejrede listeforståelser.

Til sidst vil du fortsætte med at bruge NumPy og dets indbyggede funktioner til at udføre matrixmultiplikation mere effektivt.

Sådan kontrolleres om matrixmultiplikation er gyldig

Inden du skriver Python-kode til matrixmultiplikation, lad os gense det grundlæggende i matrixmultiplikation.

Matrix Multiplikation mellem to matricer A og B er kun gyldig, hvis antallet af kolonner i matrix A er lig med antallet af rækker i matrix B.

Du ville sandsynligvis have stødt på denne betingelse for matrixmultiplikation før. Men har du nogensinde undret dig over, hvorfor dette er tilfældet?

Nå, det er på grund af måden matrix multiplikation fungerer. Tag et kig på billedet nedenfor.

I vores generiske eksempel har matrix A m rækker og n kolonner. Og matrix B har n rækker og p kolonner.

Hvad er formen på produktmatrixen?

Elementet ved indeks (i, j) i den resulterende matrix C er prikproduktet af rækken i i matrix A og kolonne j af matrix B.

Så for at få et element ved et bestemt indeks i den resulterende matrix C, skal du beregne prikproduktet af den tilsvarende række og kolonne i henholdsvis matricerne A og B.

Ved at gentage processen ovenfor får du produktmatrixen C med formen mxp – med m rækker og p-kolonner, som vist nedenfor.

Og prikproduktet eller det indre produkt mellem to vektorer a og b er givet ved følgende ligning.

Lad os opsummere nu:

  • Det er tydeligt, at prikproduktet kun er defineret mellem vektorer af samme længde.
  • Så for at prikproduktet mellem en række og en kolonne er gyldigt – når du multiplicerer to matricer – skal du have dem begge til at have det samme antal elementer.
  • I ovenstående generiske eksempel har hver række i matrix A n elementer. Og hver kolonne i matrix B har også n elementer.

Hvis du ser nærmere efter, er n antallet af kolonner i matrix A, og det er også antallet af rækker i matrix B. Og det er netop grunden til, at du skal have, at antallet af kolonner i matrix A er lig med antallet rækker i matrix B.

Jeg håber, du forstår betingelsen for, at matrixmultiplikation er gyldig, og hvordan man opnår hvert element i produktmatricen.

  12 bedste elektriske skateboards, du bør få lige nu

Lad os fortsætte med at skrive noget Python-kode for at gange to matricer.

Skriv en brugerdefineret Python-funktion til at multiplicere matricer

Lad os som et første trin skrive en brugerdefineret funktion til at multiplicere matricer.

Denne funktion skal gøre følgende:

  • Accepter to matricer, A og B, som input.
  • Tjek om matrixmultiplikation mellem A og B er gyldig.
  • Hvis gyldigt, gange de to matricer A og B, og returner produktmatrix C.
  • Ellers returnerer du en fejlmeddelelse om, at matricerne A og B ikke kan ganges.

Trin 1: Generer to matricer af heltal ved hjælp af NumPy’s random.randint() funktion. Du kan også erklære matricer som indlejrede Python-lister.

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]]

Trin 2: Gå videre og definer funktionen multiplicer_matrix(A,B). Denne funktion tager to matricer A og B ind som input og returnerer produktmatrix C, hvis matrixmultiplikation er gyldig.

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."

Parsing af funktionsdefinitionen

Lad os fortsætte med at analysere funktionsdefinitionen.

Erklærer C som en global variabel: Som standard har alle variable i en Python-funktion lokalt omfang. Og du kan ikke få adgang til dem uden for funktionen. For at gøre produktmatrix C tilgængelig udefra, bliver vi nødt til at erklære den som en global variabel. Tilføj blot den globale kvalifikation før variabelnavnet.

Tjek, om matrixmultiplikation er gyldig: Brug shape-attributten til at kontrollere, om A og B kan multipliceres. For enhver array arr, arr.shape[0] og arr.form[1] angiv antallet af henholdsvis rækker og kolonner. Så hvis A.form[1] == B.form[0] kontrollerer om matrixmultiplikation er gyldig. Kun hvis denne betingelse er Sand, vil produktmatrixen blive beregnet. Ellers returnerer funktionen en fejlmeddelelse.

Brug indlejrede sløjfer til at beregne værdier: For at beregne elementerne i den resulterende matrix skal vi sløjfe gennem rækkerne af matrix A, og den ydre for loop gør dette. Den indre for-løkke hjælper os med at gå gennem søjlen i matrix B. Og den inderste for-løkke hjælper med at få adgang til hvert element i den valgte søjle.

▶️ Nu hvor vi har lært, hvordan Python-funktionen til at multiplicere matricer fungerer, lad os kalde funktionen med matricerne A og B, som vi genererede tidligere.

multiply_matrix(A,B)

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

Da matrixmultiplikation mellem A og B er gyldig, returnerer funktionen multiplikationsmatrix() produktmatrix C.

  Sådan ændres dit brugernavn på Roblox

Brug Python Nested List Comprehension til at multiplicere matricer

I det foregående afsnit skrev du en Python-funktion til at multiplicere matricer. Nu vil du se, hvordan du kan bruge indlejrede listeforståelser til at gøre det samme.

Her er den indlejrede listeforståelse for at multiplicere matricer.

I første omgang kan dette se kompliceret ud. Men vi vil parse den indlejrede listeforståelse trin for trin.

Lad os fokusere på en listeforståelse ad gangen og identificere, hvad den gør.

Vi bruger følgende generelle skabelon til listeforståelse:

[<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

▶️ Se vores guide Listeforståelse i Python – med eksempler for at få en dybdegående forståelse.

Inden du går videre, bemærk venligst, at vi gerne vil bygge den resulterende matrix C en række ad gangen.

Indlejret listeforståelse forklaret

Trin 1: Beregn en enkelt værdi i matrix C

Givet række i af matrix A og kolonne j af matrix B, giver udtrykket nedenfor indgangen ved indeks (i, j) i matrix 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

Hvis i = j = 1, vil udtrykket returnere indgang c_11 i matricen C. Så du kan få et element i en række på denne måde.

Trin 2: Byg en række i matrix C

Vores næste mål er at bygge en hel række.

For række 1 i matrix A skal du gå gennem alle kolonner i matrix B for at få en komplet række i matrix C.

Gå tilbage til skabelonen til listeforståelse.

  • Erstat med udtrykket fra trin 1, for det er det, du vil gøre.
  • Udskift derefter med B_col—hver kolonne i matrix B.
  • Til sidst skal du erstatte med zip(*B) – listen, der indeholder alle kolonner i matrix B.

Og her er den første listeforståelse.

[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

Trin 3: Byg alle rækker og få matrix C

Dernæst skal du udfylde produktmatrix C ved at beregne resten af ​​rækkerne.

Og for dette skal du gå gennem alle rækker i matrix A.

Gå tilbage til listeforståelsen igen, og gør følgende.

  • Erstat med listeforståelsen fra trin 2. Husk, at vi beregnede en hel række i det foregående trin.
  • Erstat nu med A_row—hver række i matrix A.
  • Og din er selve matrixen A, mens du går gennem dens rækker.

Og her er vores sidste indlejrede listeforståelse.🎊

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

Det er tid til at verificere resultatet! ✔

# cast into <a href="https://toadmin.dk.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]]

Hvis du kigger nærmere, svarer dette til de indlejrede for-løkker, vi havde tidligere – bare at det er mere kortfattet.

Du kan også gøre dette desto mere effektivt ved at bruge nogle indbyggede funktioner. Lad os lære om dem i næste afsnit.

Brug NumPy matmul() til at multiplicere matricer i Python

np.matmul() tager to matricer ind som input og returnerer produktet, hvis matrixmultiplikation mellem inputmatricerne er gyldig.

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

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

Læg mærke til, hvordan denne metode er enklere end de to metoder, vi lærte tidligere. Faktisk kan du i stedet for np.matmul() bruge en tilsvarende @-operator, og det vil vi se med det samme.

Sådan bruges @ Operator i Python til at multiplicere matricer

I Python er @ en binær operator, der bruges til matrixmultiplikation.

Den opererer på to matricer og generelt N-dimensionelle NumPy-arrays og returnerer produktmatrixen.

Bemærk: Du skal have Python 3.5 og nyere for at bruge @-operatoren.

Sådan kan du bruge det.

C = [email protected]
print(C)

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

Bemærk, at produktmatrix C er den samme som den, vi fik tidligere.

Kan du bruge np.dot() til at multiplicere matricer?

Hvis du nogensinde er stødt på kode, der bruger np.dot() til at multiplicere to matricer, er det sådan her.

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

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

Du vil se, at np.dot(A, B) også returnerer den forventede produktmatrix.

Dog som pr NumPy-dokumenterskal du kun bruge np.dot() til at beregne prikproduktet af to endimensionelle vektorer og ikke til matrixmultiplikation.

Husk fra det foregående afsnit, at elementet ved indeks (i, j) af produktmatrix C er prikproduktet af rækken i af matrix A og kolonnen j af matrix B.

Da NumPy implicit udsender denne punktproduktoperation til alle rækker og alle kolonner, får du den resulterende produktmatrix. Men for at holde din kode læsbar og undgå tvetydighed, brug i stedet np.matmul() eller @-operatoren.

Konklusion

🎯 I denne tutorial har du lært følgende.

  • Betingelse for, at matrixmultiplikation er gyldig: antal kolonner i matrix A = antal rækker i matrix B.
  • Sådan skriver du en brugerdefineret Python-funktion, der kontrollerer, om matrixmultiplikation er gyldig, og returnerer produktmatrixen. Brødteksten af ​​funktionen bruger indlejret til sløjfer.
  • Dernæst lærte du, hvordan du bruger indlejrede listeforståelser til at multiplicere matricer. De er mere kortfattede end til loops, men er tilbøjelige til læsbarhedsproblemer.
  • Endelig lærte du at bruge NumPy indbyggede funktion np.matmul() til at multiplicere matricer og hvordan dette er det mest effektive i forhold til hastighed.
  • Du lærte også om @-operatoren til at gange to matricer i Python.

Og det afslutter vores diskussion om matrixmultiplikation i Python. Som et næste trin kan du lære, hvordan du kontrollerer, om et tal er primtal i Python. Eller løs interessante problemer på Python-strenge.

God læring!🎉