Jak zmienić kształt tablic NumPy w Pythonie?

W tym samouczku dowiesz się, jak używać NumPy reshape() do przekształcania tablic NumPy bez zmiany oryginalnych danych.

Podczas pracy z tablicami Numpy często możesz chcieć przekształcić istniejącą tablicę w tablicę o różnych wymiarach. Może to być szczególnie przydatne podczas przekształcania danych w wielu krokach.

A NumPy reshape() pomaga ci to łatwo zrobić. W ciągu następnych kilku minut nauczysz się składni, jak używać funkcji reshape(), a także przekształcać tablice w inne wymiary.

Co to jest zmiana kształtu w tablicach NumPy?

Podczas pracy z tablicami NumPy możesz najpierw utworzyć jednowymiarową tablicę liczb. A następnie przekształć go w tablicę o żądanym wymiarze.

Jest to szczególnie przydatne, gdy wymiary nowej tablicy nie są początkowo znane lub są wywnioskowane podczas wykonywania. Lub może być również możliwe, że pewien etap przetwarzania danych wymaga, aby dane wejściowe miały określony kształt.

Tutaj przydaje się zmiana kształtu.

Rozważmy na przykład poniższą ilustrację. Mamy wektor — jednowymiarową tablicę 6 elementów. Możemy przekształcić go w tablice o kształtach 2×3, 3×2, 6×1 i tak dalej.

▶️ Aby podążać za przykładami w tym samouczku, musisz mieć zainstalowany Python i NumPy. Jeśli nie masz jeszcze NumPy, zapoznaj się z naszym przewodnikiem instalacji NumPy.

Możesz teraz zaimportować NumPy pod aliasem np, uruchamiając: import numpy as np.

Przejdźmy do nauki składni w następnej sekcji.

Składnia funkcji przekształcenia NumPy()

Oto składnia użycia NumPy reshape():

np.reshape(arr, newshape, order="C"|'F'|'A')
  • arr to dowolny poprawny obiekt tablicy NumPy. Tutaj jest to tablica do przekształcenia.
  • newshape to kształt nowej tablicy. Może to być liczba całkowita lub krotka.
  • Gdy newshape jest liczbą całkowitą, zwracana tablica jest jednowymiarowa.
  • kolejność odnosi się do kolejności, w jakiej chcesz czytać elementy tablicy, która ma zostać zmieniona.
  • Domyślna wartość to „C”, co oznacza, że ​​elementy oryginalnej tablicy będą odczytywane w kolejności indeksowania podobnej do C (zaczynając od 0)
  • „F” oznacza indeksowanie podobne do Fortran (zaczynając od 1). A „A” czyta elementy w kolejności podobnej do C lub Fortran, w zależności od układu pamięci tablicy arr.

Więc co zwraca np.reshape()?

Jeśli to możliwe, zwraca zmieniony kształt oryginalnej tablicy. W przeciwnym razie zwraca kopię tablicy.

W powyższym wierszu wspomnieliśmy, że funkcja NumPy reshape() będzie próbowała zwrócić widok, gdy tylko jest to możliwe. W przeciwnym razie zwraca kopię. Przejdźmy do omówienia różnic między widokiem a kopią.

Widok a kopia tablic NumPy

Jak sama nazwa wskazuje, kopia jest kopią oryginalnej tablicy. Wszelkie zmiany wprowadzone w kopii nie wpłyną na oryginalną tablicę.

Z drugiej strony, widok po prostu odnosi się do zmienionego widoku oryginalnej tablicy. Oznacza to, że wszelkie zmiany wprowadzone w widoku wpłyną również na oryginalną tablicę i na odwrót.

Użyj NumPy reshape(), aby zmienić kształt tablicy 1D na tablice 2D

#1. Zacznijmy od utworzenia przykładowej tablicy za pomocą np. pomarańczowy().

Potrzebujemy tablicy 12 liczb, od 1 do 12, zwanej arr1. Ponieważ funkcja NumPy arange() domyślnie wyklucza punkt końcowy, ustaw wartość zatrzymania na 13.

Teraz użyjmy powyższej składni i przekształć arr1 z 12 elementami w tablicę 2D o kształcie (4,3). Nazwijmy to arr2 z 4 wierszami i 3 kolumnami.

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)

Przyjrzyjmy się oryginalnym i zmienionym tablicom.

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

Zamiast przekazywać tablicę jako argument np.reshape(), możesz również wywołać metodę .reshape() na oryginalnej tablicy.

Możesz uruchomić dir(arr1) i wyświetli listę wszystkich możliwych metod i atrybutów, których możesz użyć w obiekcie tablicy arr1.

dir(arr1)

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

W powyższej komórce kodu widać, że .reshape() jest prawidłową metodą do użycia w istniejącej tablicy NumPy arr1.

▶️ Możesz więc również użyć poniższej uproszczonej składni, aby zmienić kształt tablic NumPy.

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

W dalszej części tego samouczka użyjmy tej składni w naszych przykładach.

#2. Spróbujmy przekształcić nasz 12-elementowy wektor w tablicę 12 x 1.

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)

W poniższych danych wyjściowych widać, że tablica została zmieniona zgodnie z potrzebami.

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

❔ Jak więc sprawdzić, czy otrzymaliśmy kopię lub widok?

Aby to sprawdzić, możesz wywołać atrybut base na zwróconej tablicy.

  • Jeśli tablica jest kopią, atrybutem podstawowym będzie Brak.
  • Jeśli tablica jest widokiem, atrybutem podstawowym będzie oryginalna tablica.

Zweryfikujmy to szybko.

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

Jak widać, atrybut base atrybutu arr3 zwraca oryginalną tablicę. Oznacza to, że otrzymaliśmy widok oryginalnej tablicy.

#3. Teraz spróbujmy przekształcić wektor w inną poprawną tablicę 2 x 6.

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)

A oto wynik:

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

W następnej sekcji przekształćmy arr1 w tablicę 3D.

Użyj NumPy reshape(), aby zmienić kształt tablicy 1D na tablice 3D

Aby zmienić kształt arr1 na tablicę 3D, ustawmy żądane wymiary na (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)

Stworzyliśmy teraz tablicę 3D z tymi samymi 12 elementami, co oryginalna tablica 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]]]

Jak debugować błędy wartości podczas przekształcania?

Jeśli pamiętasz składnię, zmiana kształtu jest ważna tylko wtedy, gdy iloczyn wymiarów jest równy liczbie elementów w tablicy.

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)

Tutaj próbujesz przekształcić tablicę 12-elementową w tablicę 4×4 z 16 elementami. Interpreter zgłasza błąd wartości, jak widać poniżej.

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)

Aby uniknąć takich błędów, możesz użyć -1, aby automatycznie wywnioskować kształt dla jednego z wymiarów — na podstawie całkowitej liczby elementów.

Na przykład, jeśli znasz wcześniej n – 1 wymiarów, możesz użyć -1, aby wywnioskować n-ty wymiar w zmienionej tablicy.

Jeśli masz tablicę 24-elementową i chcesz ją przekształcić w tablicę 3D. Załóżmy, że potrzebujesz 3 wierszy i 4 kolumn. Możesz przekazać wartość -1 wzdłuż trzeciego wymiaru.

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

Gdy przyjrzysz się kształtowi tablicy kształtu, zobaczysz, że zmieniona tablica ma kształt 2 wzdłuż trzeciego wymiaru.

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)

Jest to szczególnie pomocne przy spłaszczaniu tablicy. Dowiesz się o tym w następnej sekcji.

Użyj NumPy reshape(), aby spłaszczyć tablicę

Są chwile, kiedy trzeba było wrócić z tablic N-wymiarowych do tablicy spłaszczonej. Załóżmy, że chcesz spłaszczyć obraz do długiego wektora pikseli.

Zakodujmy prosty przykład, wykonując następujące kroki:

  • Wygeneruj tablicę obrazów w skali szarości 3 x 3, img_arr — z pikselami w zakresie od 0 do 255.
  • Następnie spłaszcz ten img_arr i wydrukuj spłaszczoną tablicę flat_arr.
  • Wydrukuj również kształty img_arr i flat_arr do weryfikacji.
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}")

Oto wynik.

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

W powyższej komórce kodu widać, że flat_arr jest wektorem 1D wartości pikseli z 9 elementami.

Podsumowując👩‍🏫

Czas szybko przejrzeć to, czego się nauczyliśmy.

  • Użyj np.reshape(arr, newshape), aby zmienić kształt arr na kształt określony w newshape. newshape to krotka określająca wymiary zmienionej tablicy.
  • Alternatywnie użyj arr.reshape(d0, d1, …, dn), aby zmienić kształt arr na d0 x d1 x … x dn
  • Sprawdź, czy d0 * d1 * …* dn = N, liczba elementów w oryginalnej tablicy, aby uniknąć błędów wartości podczas przekształcania.
  • Użyj -1 dla co najwyżej jednego wymiaru w nowym kształcie, jeśli chcesz, aby wymiar był wywnioskowany automatycznie.
  • Na koniec możesz użyć arr.reshape(-1) do spłaszczenia tablicy.

Teraz, gdy już wiesz, jak używać funkcji NumPy reshape(), dowiedz się, jak działa funkcja NumPy linspace().

Możesz wypróbować przykłady kodu w notesie Jupyter, jeśli chcesz. Jeśli szukasz innych środowisk programistycznych, zapoznaj się z naszym przewodnikiem po alternatywach dla Jupytera.