I denne veiledningen vil vi utforske hvordan du kan benytte NumPy sin `reshape()`-funksjon for å endre strukturen til NumPy-matriser, uten at dette påvirker de underliggende dataene.
Ofte, når du jobber med numeriske data i form av NumPy-matriser, kan det være behov for å transformere en matrise til en annen med endret dimensjon. Dette kan vise seg å være meget nyttig, spesielt når data gjennomgår flere steg av prosessering.
NumPy sin `reshape()`-funksjon tilbyr en lettvint metode for å oppnå dette. I løpet av de kommende minuttene vil du bli kjent med syntaksen for `reshape()`, samt lære hvordan du endrer dimensjonene til matriser.
Hva betyr omforming av NumPy-matriser?
Når man benytter NumPy-matriser, kan det være vanlig å starte med en 1-dimensjonal matrise som inneholder tall. Deretter kan denne matrisen omformes til en ny matrise med ønsket dimensjon.
Dette er spesielt nyttig i tilfeller der dimensjonene til den nye matrisen ikke er kjent på forhånd, eller blir bestemt under kjøring av koden. Det kan også hende at et konkret databehandlingstrinn krever at inndataene har en spesifikk struktur.
Det er her omforming kommer til nytte.
Tenk deg for eksempel en vektor – en endimensjonal matrise med seks elementer. Denne vektoren kan omformes til matriser med formene 2×3, 3×2, 6×1 og så videre.
▶️ For å følge eksemplene i denne veiledningen, sørg for at du har Python og NumPy installert. Hvis du mangler NumPy, kan du finne veiledning for installasjon her.
Du kan nå importere NumPy under aliaset `np` ved å kjøre: `import numpy as np`.
La oss nå gå videre til syntaksen for `reshape()`-funksjonen.
Syntaks for NumPy `reshape()`
Her er syntaksen for hvordan du bruker NumPy sin `reshape()`-funksjon:
np.reshape(arr, newshape, order="C"|'F'|'A')
- `arr` er et vilkårlig gyldig NumPy-matriseobjekt. Dette er matrisen du ønsker å omforme.
- `newshape` er formen til den nye matrisen. Dette kan være enten et heltall eller en tuppel.
- Dersom `newshape` er et heltall, vil den returnerte matrisen være endimensjonal.
- `order` spesifiserer i hvilken rekkefølge elementene i den opprinnelige matrisen skal leses.
- Standardverdien er «C», som indikerer at elementene i den opprinnelige matrisen leses i en C-lignende indekseringsrekkefølge (starter med 0).
- «F» står for Fortran-lignende indeksering (starter med 1). Og «A» leser elementene i enten C-lignende eller Fortran-lignende rekkefølge, avhengig av hvordan matrisen `arr` er lagret i minnet.
Hva returnerer så `np.reshape()`?
Funksjonen returnerer en omformet visning av den opprinnelige matrisen hvis dette er mulig. I motsatt fall returneres en kopi av matrisen.
Vi nevnte at NumPy sin `reshape()`-funksjon vil forsøke å returnere en visning der det lar seg gjøre. La oss nå utforske forskjellene mellom en visning og en kopi.
Visning kontra kopi av NumPy-matriser
Som navnet antyder, er en kopi en ny, uavhengig utgave av den opprinnelige matrisen. Endringer i kopien vil ikke påvirke den opprinnelige matrisen.
En visning, derimot, er en omformet presentasjon av den opprinnelige matrisen. Dette innebærer at enhver endring som gjøres i visningen også vil endre den opprinnelige matrisen, og omvendt.
Bruk NumPy `reshape()` for å omforme en 1D-matrise til en 2D-matrise
#1. La oss starte med å generere en prøvematrise ved hjelp av `np.arange()`.
Vi trenger en matrise bestående av 12 tall, fra 1 til 12. La oss kalle denne matrisen `arr1`. Siden NumPy sin `arange()`-funksjon ekskluderer endepunktet som standard, må vi sette stoppverdien til 13.
La oss nå bruke syntaksen vi har lært og omforme `arr1` (som består av 12 elementer) til en 2D-matrise med formen (4,3). Vi kaller denne nye matrisen `arr2`, som vil ha 4 rader og 3 kolonner.
import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:n") print(arr1) # Reshape array arr2 = np.reshape(arr1,(4,3)) print("nReshaped array:") print(arr2)
La oss ta en titt på den opprinnelige og den omformede matrisen:
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]
I stedet for å sende inn matrisen som et argument til `np.reshape()`, kan vi også kalle metoden `.reshape()` på den opprinnelige matrisen.
Ved å kjøre `dir(arr1)` vil du få en oversikt over alle tilgjengelige metoder og attributter du kan bruke på matriseobjektet `arr1`.
dir(arr1) # Output [ ... ... 'reshape' ... .. ]
I koden over ser vi at `.reshape()` er en gyldig metode for å bruke på den eksisterende NumPy-matrisen `arr1`.
▶️ Du kan derfor benytte følgende forenklede syntaks for å omforme NumPy-matriser:
arr.reshape(d0,d1,...,dn) # hvor: # d0, d1,..,dn er dimensjonene til den omformede matrisen # d0 * d1 * ...* dn = N, antall elementer i arr
I de resterende eksemplene i denne veiledningen vil vi bruke denne forkortede syntaksen.
#2. La oss forsøke å omforme vår 12-elements vektor til en 12 x 1 matrise.
import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:n") print(arr1) # Reshape array arr3 = arr1.reshape(12,1) print("nReshaped array:") print(arr3)
Utdataene under viser at matrisen har blitt omformet som ønsket.
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12]]
❔ Hvordan kan vi vite om vi har fått en kopi eller en visning?
Dette kan du sjekke ved å benytte attributtet `base` på den returnerte matrisen.
- Dersom matrisen er en kopi, vil `base`-attributtet være `None`.
- Dersom matrisen er en visning, vil `base`-attributtet være den opprinnelige matrisen.
La oss bekrefte dette:
arr3.base # Output array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
Som vi ser, returnerer `base`-attributtet til `arr3` den opprinnelige matrisen. Dette betyr at vi har mottatt en visning av den opprinnelige matrisen.
#3. La oss nå omforme vektoren til en annen gyldig matrise, nemlig en 2 x 6 matrise.
import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:n") print(arr1) # Reshape array arr4 = arr1.reshape(2,6) print("nReshaped array:") print(arr4)
Her er utdataene:
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[ 1 2 3 4 5 6] [ 7 8 9 10 11 12]]
I neste avsnitt skal vi omforme `arr1` til en 3D-matrise.
Bruk NumPy `reshape()` for å omforme en 1D-matrise til en 3D-matrise
For å omforme `arr1` til en 3D-matrise, lar vi de ønskede dimensjonene være (1, 4, 3).
import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:n") print(arr1) # Reshape array arr3D = arr1.reshape(1,4,3) print("nReshaped array:") print(arr3D)
Vi har nå konstruert en 3D-matrise med de samme 12 elementene som i den opprinnelige matrisen `arr1`.
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] Reshaped array: [[[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]]
Hvordan feilsøke verdifeil ved omforming
Som vi husker fra syntaksen, er omforming kun gyldig når produktet av dimensjonene tilsvarer antall elementer i matrisen.
import numpy as np arr1 = np.arange(1,13) print("Original array, before reshaping:n") print(arr1) # Reshape array arr2D = arr1.reshape(4,4) print("nReshaped array:") print(arr2D)
I eksemplet over forsøker vi å omforme en 12-elements matrise til en 4×4 matrise, som krever 16 elementer. Tolken vil kaste en verdifeil, som vist nedenfor.
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12] ----------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-11-63552bcc8c37> in <module>() 6 7 # Reshape array ----> 8 arr2 = arr1.reshape(4,4) 9 print("nReshaped array:") 10 print(arr2) ValueError: cannot reshape array of size 12 into shape (4,4)
For å unngå slike feil kan du bruke `-1` for automatisk å utlede formen til en av dimensjonene – basert på det totale antall elementer.
For eksempel, hvis du kjenner `n – 1` dimensjoner på forhånd, kan du bruke `-1` for å utlede den n-te dimensjonen i den omformede matrisen.
Dersom du har en matrise med 24 elementer, og du ønsker å omforme den til en 3D-matrise, og du trenger 3 rader og 4 kolonner. Da kan du spesifisere verdien `-1` langs den tredje dimensjonen.
import numpy as np arr1 = np.arange(1,25) print("Original array, before reshaping:n") print(arr1) # Reshape array arr_res = arr1.reshape(4,3,-1) print("nReshaped array:") print(arr_res) print(f"Shape of arr_res:{arr_res.shape}")
Ved å undersøke formen til den omformede matrisen, ser vi at matrisen har formen 2 langs den tredje dimensjonen.
Original array, before reshaping: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] Reshaped array: [[[ 1 2] [ 3 4] [ 5 6]] [[ 7 8] [ 9 10] [11 12]] [[13 14] [15 16] [17 18]] [[19 20] [21 22] [23 24]]] Shape of arr_res:(4, 3, 2)
Dette er spesielt nyttig for å flate ut en matrise, som vi skal se i neste avsnitt.
Bruk NumPy `reshape()` for å flate ut en matrise
Av og til kan det være nødvendig å gå fra N-dimensjonale matriser til en flat matrise. For eksempel kan det være ønskelig å flate ut et bilde til en lang vektor av piksler.
La oss lage et enkelt eksempel der vi følger disse stegene:
- Generer en 3×3 gråtonebildematrise, `img_arr`, med pikselverdier i området 0 til 255.
- Deretter flater vi ut `img_arr` og skriver ut den flate matrisen, `flat_arr`.
- Til slutt skriver vi ut formene til både `img_arr` og `flat_arr` for å bekrefte resultatet.
img_arr = np.random.randint(0, 255, (3,3)) print(img_arr) print(f"Shape of img_arr: {img_arr.shape}") flat_arr = img_arr.reshape(-1) print(flat_arr) print(f"Shape of flat_arr: {flat_arr.shape}")
Her er resultatet:
[[195 145 77] [ 63 193 223] [215 43 36]] Shape of img_arr: (3, 3) [195 145 77 63 193 223 215 43 36] Shape of flat_arr: (9,)
I koden over ser vi at `flat_arr` er en 1D-vektor med pikselverdiene, og inneholder 9 elementer.
Oppsummering 👩🏫
La oss oppsummere det vi har lært i dag:
- Bruk `np.reshape(arr, newshape)` for å endre formen på matrisen `arr` til formen som er spesifisert i `newshape`. `newshape` er en tuppel som spesifiserer dimensjonene til den omformede matrisen.
- Alternativt kan du bruke `arr.reshape(d0, d1, …, dn)` for å omforme `arr` til å ha formen `d0 x d1 x … x dn`.
- Sørg for at `d0 * d1 * … * dn = N`, hvor `N` er antall elementer i den opprinnelige matrisen, for å unngå verdifeil under omformingen.
- Bruk `-1` for maksimalt én dimensjon i den nye formen dersom du ønsker at dimensjonen skal utledes automatisk.
- Til slutt kan du bruke `arr.reshape(-1)` for å flate ut matrisen.
Nå som du vet hvordan du kan bruke NumPy sin `reshape()`-funksjon, anbefaler vi at du lærer mer om NumPy sin `linspace()`-funksjon.
Du kan gjerne teste kodeeksemplene i en Jupyter Notebook hvis du ønsker det. Hvis du er på utkikk etter andre utviklingsmiljøer, kan du se vår veiledning om Jupyter-alternativer.