Sådan omformes NumPy-arrays i Python

I denne øvelse lærer du, hvordan du bruger NumPy reshape() til at omforme NumPy-arrays uden at ændre de originale data.

Når du arbejder med Numpy-arrays, vil du måske ofte omforme et eksisterende array til et array af forskellige dimensioner. Dette kan være særligt nyttigt, når du transformerer data i flere trin.

Og NumPy reshape() hjælper dig med at gøre det nemt. I løbet af de næste par minutter vil du lære syntaksen for at bruge reshape(), og også omforme arrays til forskellige dimensioner.

Hvad er omformning i NumPy-arrays?

Når du arbejder med NumPy-arrays, vil du måske først oprette et 1-dimensionelt array af tal. Og omform den derefter til en matrix med den ønskede dimension.

Dette er især nyttigt, når dimensionerne af det nye array ikke kendes til at begynde med eller udledes under udførelsen. Eller det kan også være muligt, at et bestemt databehandlingstrin kræver, at inputtet har en bestemt form.

Her er det, hvor omformning er praktisk.

Overvej for eksempel følgende illustration. Vi har en vektor – en endimensionel række af 6 elementer. Og vi kan omforme det til arrays af former 2×3, 3×2, 6×1, og så videre.

▶️ For at følge eksemplerne i denne tutorial skal du have Python og NumPy installeret. Hvis du ikke har NumPy endnu, så tjek vores NumPy installationsvejledning.

Du kan nu gå videre og importere NumPy under aliasset np, ved at køre: import numpy som np.

Lad os fortsætte med at lære syntaksen i næste afsnit.

Syntaks for NumPy omformning()

Her er syntaksen for at bruge NumPy omformning():

np.reshape(arr, newshape, order="C"|'F'|'A')
  • arr er et hvilket som helst gyldigt NumPy-array-objekt. Her er det arrayet, der skal omformes.
  • newshape er formen på det nye array. Det kan enten være et heltal eller en tupel.
  • Når newshape er et heltal, er det returnerede array endimensionelt.
  • rækkefølge refererer til den rækkefølge, som du gerne vil læse i elementerne i arrayet, der skal omformes.
  • Standardværdien er ‘C’, hvilket betyder, at elementerne i det originale array vil blive læst i en C-lignende indekseringsrækkefølge (startende med 0)
  • ‘F’ står for Fortran-lignende indeksering (startende med 1). Og ‘A’ læser elementerne ind i enten C-lignende eller Fortran-lignende rækkefølge afhængigt af hukommelseslayoutet af array-arr.
  Tjek, om du har brug for briller med dette online synskema

Så hvad returnerer np.reshape()?

Det returnerer en omformet visning af det originale array, hvis det er muligt. Ellers returnerer den en kopi af arrayet.

I ovenstående linje nævnte vi, at NumPy reshape() ville forsøge at returnere en visning, når det var muligt. Ellers returnerer den en kopi. Lad os fortsætte med at diskutere forskellene mellem en visning og en kopi.

Vis vs. kopi af NumPy-arrays

Som navnet antyder, er kopi en kopi af det originale array. Og eventuelle ændringer i kopien vil ikke påvirke det originale array.

På den anden side refererer view blot til en omformet visning af det originale array. Det betyder, at enhver ændring, der foretages i visningen, også vil påvirke det originale array og omvendt.

Brug NumPy reshape() til at omforme 1D Array til 2D Arrays

#1. Lad os starte med at oprette sample-arrayet vha np.arange().

Vi har brug for en matrix med 12 tal, fra 1 til 12, kaldet arr1. Da funktionen NumPy arange() udelukker slutpunktet som standard, skal du indstille stopværdien til 13.

Lad os nu bruge ovenstående syntaks og omforme arr1 med 12 elementer til et 2D-array af form (4,3). Lad os kalde dette arr2 med 4 rækker 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)

Lad os tage et kig på de originale og omformede arrays.

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 at indsætte arrayet som et argument np.reshape(), kan du også kalde .reshape()-metoden på det originale array.

Du kan køre dir(arr1), og det vil liste ned alle de mulige metoder og attributter, som du kan bruge på array-objektet arr1.

dir(arr1)

# Output 
[
...
...
'reshape'
...
..
]

I ovenstående kodecelle kan du se, at .reshape() er en gyldig metode til brug på det eksisterende NumPy-array arr1.

▶️ Så du kan også bruge følgende forenklede syntaks til at omforme NumPy-arrays.

arr.reshape(d0,d1,...,dn)

# where:

# d0, d1,..,dn are the dimensions of the reshaped array

# d0 * d1 * ...* dn = N, the number of elements in arr

For resten af ​​denne tutorial, lad os bruge denne syntaks i vores eksempler.

#2. Lad os prøve at omforme vores 12-element vektor til en 12 x 1 matrix.

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)

I outputtet nedenfor kan du se, at arrayet er blevet omformet efter behov.

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

❔ Så hvordan kontrollerer vi, om vi har fået en kopi eller en visning?

  Hvad er Denuvo, og hvorfor hader spillere det?

For at kontrollere dette kan du kalde basisattributten på det returnerede array.

  • Hvis arrayet er en kopi, vil basisattributten være Ingen.
  • Hvis arrayet er en visning, vil basisattributten være den originale array.

Lad os hurtigt bekræfte dette.

arr3.base
# Output
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

Som du kan se, returnerer basisattributten for arr3 det oprindelige array. Det betyder, at vi har modtaget en visning af det originale array.

#3. Lad os nu prøve at omforme vektoren til en anden gyldig 2 x 6 matrix.

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)

Og her er outputtet:

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

Lad os i næste afsnit omforme arr1 til et 3D-array.

Brug NumPy reshape() til at omforme 1D Array til 3D Arrays

For at omforme arr1 til et 3D-array, lad os indstille de ønskede dimensioner til (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 nu skabt et 3D-array med de samme 12 elementer som det originale array 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]]]

Sådan fejlfindes værdifejl under omformning

Hvis du husker syntaksen, er omformning kun gyldig, når produktet af dimensionerne er lig med antallet af elementer i arrayet.

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)

Her forsøger du at omforme et 12-element-array til et 4×4-array med 16 elementer. Tolken kaster en værdifejl, 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 at undgå sådanne fejl kan du bruge -1 til automatisk at udlede formen for en af ​​dimensionerne – baseret på det samlede antal elementer.

For eksempel, hvis du kender n – 1 dimensioner på forhånd, kan du bruge -1 til at udlede den n-te dimension i det omformede array.

  Tjek, om din computer er kompatibel med Oculus Rift

Hvis du har et array med 24 elementer, og du gerne vil omforme det til et 3D-array. Antag, at du har brug for 3 rækker og 4 kolonner. Du kan indtaste værdien -1 langs den tredje dimension.

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}")

Når du undersøger formen på formarrayet, kan du se, at den omformede matrix har en form på 2 langs den tredje dimension.

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 især nyttigt til at udflade et array. Og det lærer du om i næste afsnit.

Brug NumPy reshape() til at flade et array

Der er tidspunkter, hvor du bliver nødt til at gå tilbage fra N-dimensionelle arrays til en fladtrykt array. Antag, at du vil flad et billede til en lang vektor af pixels.

Lad os kode et simpelt eksempel ved at bruge følgende trin:

  • Generer en 3 x 3 gråtonebilledarray, img_arr—med pixels i området 0 til 255.
  • Dernæst skal du flad denne img_arr og udskrive den fladtrykte array, flat_arr.
  • Udskriv også formerne af img_arr og flat_arr for at bekræfte.
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 outputtet.

[[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 ovenstående kodecelle kan du se, at flat_arr er en 1D vektor af pixelværdier med 9 elementer.

Opsummering👩‍🏫

Det er tid til hurtigt at gennemgå, hvad vi har lært.

  • Brug np.reshape(arr, newshape) til at omforme arr til den form, der er angivet i newshape. newshape er en tuple, der angiver dimensionerne af det omformede array.
  • Alternativt kan du bruge arr.reshape(d0, d1, …, dn) til at omforme arr til at have formen d0 x d1 x … x dn
  • Tjek, om d0 * d1 * …* dn = N, antallet af elementer i det originale array, for at undgå værdifejl under omformning.
  • Brug -1 for højst én dimension i den nye form, hvis du ønsker, at dimensionen automatisk skal udledes.
  • Til sidst kan du bruge arr.reshape(-1) til at udjævne arrayet.

Nu hvor du ved, hvordan du bruger NumPy reshape(), skal du lære, hvordan funktionen NumPy linspace() fungerer.

Du kan prøve kodeeksemplerne i Jupyter notesbog, hvis du vil. Hvis du leder efter andre udviklingsmiljøer, så tjek vores guide om Jupyter-alternativer.