I denna handledning kommer du att utforska hur du kan använda NumPy’s `reshape()`-funktion för att ändra formen på NumPy-arrayer utan att förändra de underliggande data.
När du hanterar NumPy-arrayer kan det ofta uppstå behov av att omvandla en existerande array till en array med andra dimensioner. Det kan vara särskilt användbart när du bearbetar data i olika steg.
NumPy’s `reshape()`-funktion gör denna process enkel. Under de kommande minuterna kommer du att lära dig syntaxen för `reshape()` och hur du kan omforma arrayer till olika dimensioner.
Vad innebär omformning av NumPy-arrayer?
När man arbetar med NumPy-arrayer kan det vara så att man först skapar en endimensionell array med numeriska värden, och sedan vill man omforma den till en array med specifika dimensioner.
Detta är särskilt användbart när dimensionerna för den nya arrayen inte är kända från början, eller bestäms under körningen av programmet. Det kan också vara så att en viss bearbetningsprocess kräver att indata har en specifik form.
Det är här omformning kommer in i bilden.
Tänk dig följande scenario: vi har en vektor – en endimensionell array med 6 element. Denna vektor kan vi omforma till arrayer med formerna 2×3, 3×2, 6×1 och så vidare.
▶️ För att kunna följa exemplen i denna handledning behöver du ha Python och NumPy installerat. Om du inte har NumPy ännu, kan du hitta installationsanvisningar i vår guide för NumPy-installation.
Nu kan vi fortsätta genom att importera NumPy med aliaset `np`, genom att köra: `import numpy as np`.
Låt oss nu gå vidare och studera syntaxen i nästa avsnitt.
Syntax för NumPy `reshape()`
Här är syntaxen för att använda NumPy `reshape()`:
np.reshape(arr, newshape, order="C"|'F'|'A')
- `arr` är vilket giltigt NumPy-arrayobjekt som helst. Det är arrayen som ska omformas.
- `newshape` är formen på den nya arrayen. Det kan vara antingen ett heltal eller en tupel.
- Om `newshape` är ett heltal kommer den returnerade arrayen att vara endimensionell.
- `order` specificerar den ordning i vilken elementen i den array som ska omformas ska läsas.
- Standardvärdet är ’C’, vilket innebär att elementen i den ursprungliga arrayen läses i en C-liknande indexeringsordning (med start från 0).
- ’F’ står för Fortran-liknande indexering (med start från 1). ’A’ läser in elementen i antingen C-liknande eller Fortran-liknande ordning, beroende på arrayens minneslayout.
Så, vad returnerar `np.reshape()`?
Den returnerar en omformad *vy* av den ursprungliga arrayen om möjligt. Annars returneras en *kopia* av arrayen.
I föregående stycke nämnde vi att NumPy `reshape()` försöker returnera en vy när det är möjligt. Låt oss nu utforska skillnaden mellan en vy och en kopia.
Vy kontra kopia av NumPy-arrayer
Som namnet antyder är en kopia en exakt kopia av den ursprungliga arrayen. Ändringar som görs i kopian påverkar inte den ursprungliga arrayen.
En vy, å andra sidan, är endast en omformad vy av den ursprungliga arrayen. Det betyder att alla ändringar som görs i vyn kommer att påverka den ursprungliga arrayen, och vice versa.
Använd NumPy `reshape()` för att omforma en 1D-array till en 2D-array
#1. Låt oss börja med att skapa en testarray med hjälp av `np.arange()`.
Vi behöver en array med 12 tal, från 1 till 12, som vi kallar `arr1`. Eftersom funktionen NumPy `arange()` exkluderar slutpunkten som standard, anger vi stoppvärdet till 13.
Nu använder vi syntaxen ovan och omformar `arr1` med 12 element till en 2D-array med formen (4,3). Vi kallar denna array för `arr2` som ska ha 4 rader och 3 kolumner.
import numpy as np arr1 = np.arange(1,13) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr2 = np.reshape(arr1,(4,3)) print("\nOmformad array:") print(arr2)
Låt oss ta en titt på den ursprungliga och den omformade arrayen.
Ursprunglig array, före omformning: [ 1 2 3 4 5 6 7 8 9 10 11 12] Omformad array: [[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]
Istället för att skicka in arrayen som ett argument till `np.reshape()`, kan du även anropa metoden `.reshape()` direkt på den ursprungliga arrayen.
Du kan köra `dir(arr1)` för att få en lista över alla metoder och attribut som kan användas på arrayobjektet `arr1`.
dir(arr1) # Resultat [ ... ... 'reshape' ... .. ]
I ovanstående kodresultat ser du att `.reshape()` är en giltig metod som kan användas på en NumPy-array som `arr1`.
▶️ Du kan alltså använda följande förenklade syntax för att omforma NumPy-arrayer.
arr.reshape(d0,d1,...,dn) # där: # d0, d1,..,dn är dimensionerna för den omformade arrayen # d0 * d1 * ...* dn = N, antalet element i arr
I resten av denna handledning kommer vi att använda den här syntaxen i våra exempel.
#2. Låt oss försöka omforma vår 12-elementvektor till en 12 x 1 array.
import numpy as np arr1 = np.arange(1,13) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr3 = arr1.reshape(12,1) print("\nOmformad array:") print(arr3)
I resultatet nedan ser du att arrayen har omformats enligt önskemål.
Ursprunglig array, före omformning: [ 1 2 3 4 5 6 7 8 9 10 11 12] Omformad array: [[ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12]]
❔ Så, hur kan vi kontrollera om vi har fått en kopia eller en vy?
För att kontrollera detta kan du anropa attributet `base` på den returnerade arrayen.
- Om arrayen är en kopia kommer `base`-attributet att vara `None`.
- Om arrayen är en vy kommer `base`-attributet att referera till den ursprungliga arrayen.
Låt oss snabbt verifiera detta.
arr3.base # Resultat array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
Som du kan se returnerar `base`-attributet för `arr3` den ursprungliga arrayen. Det betyder att vi har fått en vy av den ursprungliga arrayen.
#3. Låt oss nu försöka omforma vektorn till en annan giltig 2 x 6 array.
import numpy as np arr1 = np.arange(1,13) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr4 = arr1.reshape(2,6) print("\nOmformad array:") print(arr4)
Här är resultatet:
Ursprunglig array, före omformning: [ 1 2 3 4 5 6 7 8 9 10 11 12] Omformad array: [[ 1 2 3 4 5 6] [ 7 8 9 10 11 12]]
I nästa avsnitt kommer vi att omforma `arr1` till en 3D-array.
Använd NumPy `reshape()` för att omforma en 1D-array till en 3D-array
För att omforma `arr1` till en 3D-array, låt oss ange de önskade dimensionerna till (1, 4, 3).
import numpy as np arr1 = np.arange(1,13) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr3D = arr1.reshape(1,4,3) print("\nOmformad array:") print(arr3D)
Vi har nu skapat en 3D-array med samma 12 element som den ursprungliga arrayen `arr1`.
Ursprunglig array, före omformning: [ 1 2 3 4 5 6 7 8 9 10 11 12] Omformad array: [[[ 1 2 3] [ 4 5 6] [ 7 8 9] [10 11 12]]]
Hur man felsöker `ValueError` under omformning
Kom ihåg att omformning bara är giltig när produkten av dimensionerna är lika med antalet element i arrayen.
import numpy as np arr1 = np.arange(1,13) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr2D = arr1.reshape(4,4) print("\nOmformad array:") print(arr2D)
Här försöker vi omforma en 12-elementsarray till en 4×4-array med 16 element. Detta genererar ett `ValueError` som visas nedan.
Ursprunglig array, före omformning: [ 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 # Omforma arrayen ----> 8 arr2 = arr1.reshape(4,4) 9 print("\nOmformad array:") 10 print(arr2) ValueError: cannot reshape array of size 12 into shape (4,4)
För att undvika sådana fel kan du använda -1 för att automatiskt härleda formen för en av dimensionerna – baserat på det totala antalet element.
Om du exempelvis vet n – 1 dimensioner i förväg kan du använda -1 för att beräkna den n:te dimensionen i den omformade matrisen.
Om du har en array med 24 element och du vill omforma den till en 3D-array. Anta att du vill ha 4 rader och 3 kolumner. Då kan du ange värdet -1 längs den tredje dimensionen.
import numpy as np arr1 = np.arange(1,25) print("Ursprunglig array, före omformning:\n") print(arr1) # Omforma arrayen arr_res = arr1.reshape(4,3,-1) print("\nOmformad array:") print(arr_res) print(f"Form av arr_res:{arr_res.shape}")
När du undersöker formen på den resulterande arrayen, ser du att den omformade arrayen har formen 2 längs den tredje dimensionen.
Ursprunglig array, före omformning: [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] Omformad 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]]] Form av arr_res:(4, 3, 2)
Detta är särskilt användbart för att platta ut en array. Låt oss titta på det i nästa avsnitt.
Använd NumPy `reshape()` för att platta ut en array
Ibland kan det vara nödvändigt att gå tillbaka från N-dimensionella arrayer till en utplattad array. Tänk dig att du vill platta ut en bild till en lång vektor med pixlar.
Låt oss skapa ett enkelt exempel med följande steg:
- Generera en 3 x 3 gråskalebildmatris, `img_arr`, med pixlar i intervallet 0 till 255.
- Platta sedan ut denna `img_arr` och skriv ut den utplattade arrayen, `flat_arr`.
- Skriv även ut formerna för `img_arr` och `flat_arr` för att verifiera resultaten.
img_arr = np.random.randint(0, 255, (3,3)) print(img_arr) print(f"Form av img_arr: {img_arr.shape}") flat_arr = img_arr.reshape(-1) print(flat_arr) print(f"Form av flat_arr: {flat_arr.shape}")
Här är resultatet.
[[195 145 77] [ 63 193 223] [215 43 36]] Form av img_arr: (3, 3) [195 145 77 63 193 223 215 43 36] Form av flat_arr: (9,)
I ovanstående kodresultat ser du att `flat_arr` är en 1D-vektor med pixelvärden och 9 element.
Sammanfattning 👩🏫
Nu är det dags att gå igenom vad vi har lärt oss.
- Använd `np.reshape(arr, newshape)` för att omforma `arr` till den form som specificeras av `newshape`. `newshape` är en tupel som anger dimensionerna för den omformade arrayen.
- Alternativt kan du använda `arr.reshape(d0, d1, …, dn)` för att omforma `arr` till att ha formen `d0 x d1 x … x dn`.
- Kontrollera att `d0 * d1 * …* dn = N`, vilket är antalet element i den ursprungliga arrayen, för att undvika `ValueError` under omformning.
- Använd -1 för högst en dimension i den nya formen om du vill att den dimensionen ska härledas automatiskt.
- Slutligen kan du använda `arr.reshape(-1)` för att platta ut arrayen.
Nu när du vet hur du använder NumPy `reshape()`, kan du lära dig mer om hur NumPy-funktionen `linspace()` fungerar.
Du kan prova kodexemplen i en Jupyter Notebook om du vill. Om du letar efter andra utvecklingsmiljöer, kolla in vår guide om Jupyter-alternativ.