Як змінити форму масивів NumPy у Python

У цьому підручнику ви дізнаєтеся, як використовувати NumPy reshape() для зміни форми масивів NumPy без зміни вихідних даних.

Працюючи з масивами Numpy, ви часто можете змінити форму існуючого масиву на масив різних розмірів. Це може бути особливо корисним, коли ви перетворюєте дані в кілька кроків.

І NumPy reshape() допоможе вам зробити це легко. Протягом наступних кількох хвилин ви навчитеся синтаксису використання функції reshape(), а також зміните форму масивів на різні розміри.

Що таке зміна форми в масивах NumPy?

Працюючи з масивами NumPy, ви можете спочатку створити одновимірний масив чисел. А потім переформуйте його в масив із потрібним розміром.

Це особливо корисно, коли розміри нового масиву невідомі спочатку або виводяться під час виконання. Або також може бути можливим, що певний етап обробки даних вимагає, щоб вхідні дані мали певну форму.

Ось де зміна форми стане в нагоді.

Для прикладу розглянемо наступну ілюстрацію. Маємо вектор — одновимірний масив із 6 елементів. І ми можемо переформувати його в масиви форм 2×3, 3×2, 6×1 і так далі.

▶️ Щоб слідувати прикладам у цьому посібнику, вам потрібно встановити Python і NumPy. Якщо у вас ще немає NumPy, перегляньте наш посібник зі встановлення NumPy.

Тепер ви можете імпортувати NumPy під псевдонімом np, запустивши: import numpy as np.

Переходимо до вивчення синтаксису в наступному розділі.

Синтаксис NumPy reshape()

Ось синтаксис використання NumPy reshape():

np.reshape(arr, newshape, order="C"|'F'|'A')
  • arr — будь-який дійсний об’єкт масиву NumPy. Ось це масив, який потрібно змінити.
  • newshape — це форма нового масиву. Це може бути як ціле число, так і кортеж.
  • Коли newshape є цілим числом, повернутий масив є одновимірним.
  • порядок означає порядок, у якому ви бажаєте прочитати елементи масиву, який потрібно змінити.
  • Значення за замовчуванням — «C», що означає, що елементи вихідного масиву читатимуться в порядку індексування, подібному до C (починаючи з 0)
  • «F» означає індексування, подібне до Fortran (починається з 1). А ‘A’ зчитує елементи в C-подібному або Fortran-подібному порядку залежно від розташування пам’яті масиву arr.
  9 найкращих експертних мереж для прийняття обґрунтованих бізнес-рішень

Отже, що повертає np.reshape()?

Він повертає змінений вигляд вихідного масиву, якщо це можливо. В іншому випадку він повертає копію масиву.

У наведеному вище рядку ми згадали, що NumPy reshape() намагатиметься повернути перегляд, коли це можливо. В іншому випадку він повертає копію. Переходимо до обговорення відмінностей між видом і копією.

Перегляд чи копія масивів NumPy

Як випливає з назви, копія — це копія вихідного масиву. І будь-які зміни, внесені до копії, не вплинуть на оригінальний масив.

З іншого боку, перегляд просто відноситься до зміненого вигляду оригінального масиву. Це означає, що будь-яка зміна, внесена до перегляду, також вплине на вихідний масив і навпаки.

Використовуйте NumPy reshape(), щоб змінити форму 1D-масиву на 2D-масив

#1. Почнемо зі створення зразкового масиву за допомогою np.arange().

Нам потрібен масив із 12 чисел, від 1 до 12, який називається arr1. Оскільки функція NumPy arange() за замовчуванням виключає кінцеву точку, встановіть значення зупинки на 13.

Тепер скористаємося наведеним вище синтаксисом і змінимо форму arr1 із 12 елементів у двовимірний масив форми (4,3). Назвемо це arr2 із 4 рядками та 3 стовпцями.

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)

Давайте подивимося на оригінальні та змінені масиви.

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

Замість того, щоб передавати масив як аргумент np.reshape(), ви також можете викликати метод .reshape() для оригінального масиву.

Ви можете запустити dir(arr1), і він покаже список усіх можливих методів і атрибутів, які ви можете використовувати для об’єкта масиву arr1.

dir(arr1)

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

У наведеній вище клітинці коду ви можете побачити, що .reshape() є дійсним методом для використання в існуючому масиві NumPy arr1.

▶️ Отже, ви також можете використовувати наступний спрощений синтаксис, щоб змінити форму масивів 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

У решті цього посібника давайте використовувати цей синтаксис у наших прикладах.

#2. Давайте спробуємо змінити форму нашого 12-елементного вектора в масив 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)

У вихідних даних нижче ви можете побачити, що масив змінено за потреби.

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

❔ Отже, як ми перевіримо, чи отримали ми копію чи перегляд?

  Як перетворити зображення у формат PNG

Щоб перевірити це, ви можете викликати базовий атрибут у поверненому масиві.

  • Якщо масив є копією, базовим атрибутом буде None.
  • Якщо масив є представленням, базовим атрибутом буде вихідний масив.

Давайте швидко це перевіримо.

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

Як бачите, базовий атрибут arr3 повертає вихідний масив. Це означає, що ми отримали вигляд вихідного масиву.

#3. Тепер давайте спробуємо змінити форму вектора в інший дійсний масив 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)

І ось результат:

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

У наступному розділі давайте змінимо форму arr1 у тривимірний масив.

Використовуйте NumPy reshape(), щоб змінити форму 1D-масиву на 3D-масив

Щоб змінити форму arr1 на тривимірний масив, давайте встановимо потрібні розміри (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)

Тепер ми створили 3D-масив із тими самими 12 елементами, що й оригінальний масив 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]]]

Як налагодити помилки значення під час зміни форми

Якщо ви пам’ятаєте синтаксис, зміна форми дійсна лише тоді, коли добуток розмірів дорівнює кількості елементів у масиві.

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)

Тут ви намагаєтеся змінити форму масиву з 12 елементів у масив 4×4 із 16 елементами. Інтерпретатор видає помилку значення, як показано нижче.

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)

Щоб уникнути таких помилок, ви можете використовувати -1 для автоматичного визначення форми для одного з розмірів на основі загальної кількості елементів.

Наприклад, якщо ви заздалегідь знаєте n – 1 вимір, ви можете використовувати -1, щоб визначити n-й вимір у зміненому масиві.

  5 Альтернативи System Center Configuration Manager (SCCM) для виправлення робочого столу та сервера

Якщо у вас є 24-елементний масив і ви хочете змінити його форму на тривимірний масив. Припустимо, вам потрібно 3 рядки і 4 стовпці. Ви можете передати значення -1 уздовж третього виміру.

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

Коли ви вивчаєте форму масиву фігур, ви можете бачити, що змінений масив має форму 2 уздовж третього виміру.

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)

Це особливо корисно для зведення масиву. І ви дізнаєтеся про це в наступному розділі.

Використовуйте NumPy reshape(), щоб звести масив

Бувають випадки, коли вам потрібно повернутися від N-вимірних масивів до зведеного масиву. Припустімо, ви хочете звести зображення до довгого вектора пікселів.

Давайте напишемо простий приклад, виконавши такі дії:

  • Створіть масив зображень у відтінках сірого розміром 3 x 3, img_arr—з пікселями в діапазоні від 0 до 255.
  • Потім зведіть цей img_arr і роздрукуйте зведений масив flat_arr.
  • Також роздрукуйте форми img_arr і flat_arr для перевірки.
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}")

Ось результат.

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

У наведеній вище комірці коду ви можете побачити, що flat_arr — це одновимірний вектор значень пікселів із 9 елементами.

Підведення підсумків👩‍🏫

Настав час швидко повторити те, що ми навчилися.

  • Використовуйте np.reshape(arr, newshape), щоб змінити форму arr у форму, вказану в newshape. newshape — це кортеж, що визначає розміри зміненого масиву.
  • Крім того, використовуйте arr.reshape(d0, d1, …, dn), щоб змінити форму arr так, щоб він мав форму d0 x d1 x … x dn
  • Перевірте, чи d0 * d1 * …* dn = N, кількість елементів у вихідному масиві, щоб уникнути помилок значень під час зміни форми.
  • Використовуйте -1 щонайбільше для одного розміру в новій формі, якщо ви хочете, щоб розмір визначався автоматично.
  • Нарешті, ви можете використати arr.reshape(-1), щоб звести масив.

Тепер, коли ви знаєте, як використовувати NumPy reshape(), дізнайтеся, як працює функція NumPy linspace().

Ви можете спробувати приклади коду в блокноті Jupyter, якщо хочете. Якщо ви шукаєте інші середовища розробки, перегляньте наш посібник про альтернативи Jupyter.