3 måter å multiplisere matriser i Python

I denne opplæringen lærer du hvordan du multipliserer to matriser i Python.

Du begynner med å lære betingelsen for gyldig matrisemultiplikasjon og skrive en tilpasset Python-funksjon for å multiplisere matriser. Deretter vil du se hvordan du kan oppnå det samme resultatet ved å bruke nestede listeforståelser.

Til slutt vil du fortsette å bruke NumPy og dens innebygde funksjoner for å utføre matrisemultiplikasjon mer effektivt.

Hvordan sjekke om matrisemultiplikasjon er gyldig

Før du skriver Python-kode for matrisemultiplikasjon, la oss gå tilbake til det grunnleggende om matrisemultiplikasjon.

Matrisemultiplikasjon mellom to matriser A og B er kun gyldig hvis antall kolonner i matrise A er lik antall rader i matrise B.

Du ville sannsynligvis ha kommet over denne tilstanden for matrisemultiplikasjon før. Men har du noen gang lurt på hvorfor dette er tilfelle?

Vel, det er på grunn av måten matrisemultiplikasjon fungerer på. Ta en titt på bildet nedenfor.

I vårt generiske eksempel har matrise A m rader og n kolonner. Og matrise B har n rader og p kolonner.

Hva er formen på produktmatrisen?

Elementet ved indeks (i, j) i den resulterende matrisen C er punktproduktet av raden i av matrisen A, og kolonne j av matrisen B.

Så for å få et element ved en bestemt indeks i den resulterende matrisen C, må du beregne punktproduktet til den tilsvarende raden og kolonnen i matrisene A og B, henholdsvis.

Ved å gjenta prosessen ovenfor, får du produktmatrisen C av formen mxp—med m rader og p-kolonner, som vist nedenfor.

Og punktproduktet eller det indre produktet mellom to vektorer a og b er gitt ved følgende ligning.

La oss oppsummere nå:

  • Det er tydelig at prikkproduktet kun er definert mellom vektorer av lik lengde.
  • Så for at punktproduktet mellom en rad og en kolonne skal være gyldig – når du multipliserer to matriser – trenger du at begge har samme antall elementer.
  • I det generelle eksemplet ovenfor har hver rad i matrise A n elementer. Og hver kolonne i matrise B har også n elementer.

Hvis du ser nærmere på, er n antall kolonner i matrise A, og det er også antall rader i matrise B. Og dette er nettopp grunnen til at du trenger at antall kolonner i matrise A skal være lik antallet av rader i matrise B.

Jeg håper du forstår betingelsen for at matrisemultiplikasjon skal være gyldig og hvordan du får frem hvert element i produktmatrisen.

  Hvordan skjule feilverdier og indikatorer i Microsoft Excel

La oss fortsette med å skrive litt Python-kode for å multiplisere to matriser.

Skriv en tilpasset Python-funksjon for å multiplisere matriser

Som et første trinn, la oss skrive en egendefinert funksjon for å multiplisere matriser.

Denne funksjonen bør gjøre følgende:

  • Godta to matriser, A og B, som input.
  • Sjekk om matrisemultiplikasjon mellom A og B er gyldig.
  • Hvis gyldig, multipliser de to matrisene A og B, og returner produktmatrisen C.
  • Ellers, returner en feilmelding om at matrisene A og B ikke kan multipliseres.

Trinn 1: Generer to matriser med heltall ved å bruke NumPys random.randint() funksjon. Du kan også erklære matriser som nestede 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]]

Trinn 2: Fortsett og definer funksjonen multiplisere_matrise(A,B). Denne funksjonen tar inn to matriser A og B som input og returnerer produktmatrisen C hvis matrisemultiplikasjon 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 av funksjonsdefinisjonen

La oss fortsette med å analysere funksjonsdefinisjonen.

Erklær C som en global variabel: Som standard har alle variabler i en Python-funksjon lokalt omfang. Og du kan ikke få tilgang til dem fra utenfor funksjonen. For å gjøre produktmatrisen C tilgjengelig utenfra, må vi erklære den som en global variabel. Bare legg til den globale kvalifikatoren før variabelnavnet.

Sjekk om matrisemultiplikasjon er gyldig: Bruk shape-attributtet for å sjekke om A og B kan multipliseres. For enhver array arr, arr.shape[0] og arr.form[1] angi antall rader og kolonner, henholdsvis. Så hvis A.shape[1] == B.form[0] sjekker om matrisemultiplikasjon er gyldig. Bare hvis denne betingelsen er sann, vil produktmatrisen bli beregnet. Ellers returnerer funksjonen en feilmelding.

Bruk nestede løkker for å beregne verdier: For å beregne elementene i den resulterende matrisen, må vi gå gjennom radene i matrise A, og den ytre for løkke gjør dette. Den indre for-løkken hjelper oss å gå gjennom kolonnen i matrise B. Og den innerste for-løkken hjelper oss med å få tilgang til hvert element i den valgte kolonnen.

▶️ Nå som vi har lært hvordan Python-funksjonen for å multiplisere matriser fungerer, la oss kalle funksjonen med matrisene A og B som vi genererte tidligere.

multiply_matrix(A,B)

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

Siden matrisemultiplikasjon mellom A og B er gyldig, returnerer funksjonen multiplikasjonsmatrise() produktmatrisen C.

Bruk Python Nested List Comprehension for å multiplisere matriser

I forrige avsnitt skrev du en Python-funksjon for å multiplisere matriser. Nå vil du se hvordan du kan bruke nestede listeforståelser til å gjøre det samme.

  Hvordan koble til et annet lysbilde i samme PowerPoint-presentasjon

Her er den nestede listeforståelsen for å multiplisere matriser.

I begynnelsen kan dette se komplisert ut. Men vi vil analysere den nestede listeforståelsen trinn for trinn.

La oss fokusere på én listeforståelse om gangen og identifisere hva den gjør.

Vi bruker følgende generelle mal for 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

▶️ Sjekk ut vår guide Listeforståelse i Python – med eksempler for å få en dybdeforståelse.

Før du går videre, vær oppmerksom på at vi ønsker å bygge den resulterende matrisen C en rad om gangen.

Nestet listeforståelse forklart

Trinn 1: Beregn en enkelt verdi i matrisen C

Gitt rad i av matrise A og kolonne j av matrise B, gir uttrykket nedenfor oppføringen ved indeks (i, j) i matrise 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 uttrykket returnere oppføring c_11 i matrisen C. Så du kan få ett element i en rad på denne måten.

Trinn 2: Bygg én rad i matrisen C

Vårt neste mål er å bygge en hel rad.

For rad 1 i matrise A må du gå gjennom alle kolonnene i matrise B for å få en hel rad i matrise C.

Gå tilbake til malen for listeforståelse.

  • Erstatt med uttrykket fra trinn 1, fordi det er det du vil gjøre.
  • Deretter erstatter du med B_col—hver kolonne i matrise B.
  • Til slutt erstatter du med zip(*B) – listen som inneholder alle kolonnene i matrise B.

Og her er den første listeforstå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

Trinn 3: Bygg alle rader og skaff matrisen C

Deretter må du fylle ut produktmatrisen C ved å beregne resten av radene.

Og for dette må du gå gjennom alle radene i matrise A.

Gå tilbake til listeforståelsen igjen, og gjør følgende.

  • Erstatt med listeforståelsen fra trinn 2. Husk at vi beregnet en hel rad i forrige trinn.
  • Erstatt nå med A_row—hver rad i matrise A.
  • Og din er selve matrisen A, mens du går gjennom radene.

Og her er vår siste forståelse av nestede liste.🎊

[[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 på tide å verifisere resultatet! ✔

# cast into <a href="https://tipsbilk.net.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 tar en nærmere titt, tilsvarer dette den nestede for-løkkene vi hadde tidligere – bare at den er mer kortfattet.

Du kan også gjøre dette desto mer effektivt ved å bruke noen innebygde funksjoner. La oss lære om dem i neste avsnitt.

Bruk NumPy matmul() til å multiplisere matriser i Python

np.matmul() tar inn to matriser som input og returnerer produktet hvis matrisemultiplikasjon mellom inputmatrisene er gyldig.

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

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

Legg merke til hvordan denne metoden er enklere enn de to metodene vi lærte tidligere. Faktisk, i stedet for np.matmul(), kan du bruke en tilsvarende @-operator, og vi ser det med en gang.

Hvordan bruke @ Operator i Python til å multiplisere matriser

I Python er @ en binær operator som brukes til matrisemultiplikasjon.

Den opererer på to matriser, og generelt N-dimensjonale NumPy-matriser, og returnerer produktmatrisen.

Merk: Du må ha Python 3.5 og nyere for å bruke @-operatoren.

Slik kan du bruke den.

C = [email protected]
print(C)

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

Legg merke til at produktmatrisen C er den samme som den vi fikk tidligere.

Kan du bruke np.dot() til å multiplisere matriser?

Hvis du noen gang har kommet over kode som bruker np.dot() til å multiplisere to matriser, er det slik det fungerer.

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

Imidlertid, som pr NumPy-dokumenterbør du bare bruke np.dot() for å beregne punktproduktet av to endimensjonale vektorer og ikke for matrisemultiplikasjon.

Husk fra forrige avsnitt, elementet ved indeks (i, j) av produktmatrisen C er prikkproduktet av raden i av matrise A, og kolonnen j av matrise B.

Ettersom NumPy implisitt kringkaster denne punktproduktoperasjonen til alle rader og alle kolonner, får du den resulterende produktmatrisen. Men for å holde koden lesbar og unngå tvetydighet, bruk np.matmul() eller @-operatoren i stedet.

Konklusjon

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

  • Betingelse for at matrisemultiplikasjon skal være gyldig: antall kolonner i matrise A = antall rader i matrise B.
  • Hvordan skrive en tilpasset Python-funksjon som sjekker om matrisemultiplikasjon er gyldig og returnerer produktmatrisen. Brødteksten til funksjonen bruker nestet for løkker.
  • Deretter lærte du hvordan du bruker nestede listeforståelser til å multiplisere matriser. De er mer kortfattede enn for løkker, men er utsatt for problemer med lesbarhet.
  • Til slutt lærte du å bruke NumPy innebygde funksjon np.matmul() for å multiplisere matriser og hvordan dette er mest effektivt med tanke på hastighet.
  • Du lærte også om @-operatoren for å multiplisere to matriser i Python.

Og det avslutter diskusjonen vår om matrisemultiplikasjon i Python. Som et neste trinn, lær hvordan du sjekker om et tall er primtall i Python. Eller løs interessante problemer på Python-strenger.

God læring!🎉