Формы массивов: reshape, ravel, flatten

Формы массивов: reshape, ravel, flatten NumPy

Привет! В NumPy форма массива — это количество элементов по каждому измерению. Иногда нужно изменить форму массива: превратить одномерный в двумерный, или наоборот. Для этого есть три основных метода: reshape()ravel() и flatten().

В этой статье мы разберём:

  • reshape() — изменение формы
  • ravel() — преобразование в одномерный (view)
  • flatten() — преобразование в одномерный (copy)
  • Отличия между методами
  • Практические примеры

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный NumPy
  • Базовое понимание массивов и их атрибутов

Совет: Изменение формы не меняет данные, только их представление.

Основная часть

Что такое форма массива

Форма массива — это кортеж, указывающий размер по каждому измерению.

import numpy as np

# Одномерный массив
arr1 = np.array([1, 2, 3, 4, 5, 6])
print(arr1.shape)   # (6,)

# Двумерный массив
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2.shape)   # (2, 3)

Совет: Количество элементов должно совпадать при изменении формы.

reshape() — изменение формы

reshape() изменяет форму массива, не меняя данные.

arr = np.array([1, 2, 3, 4, 5, 6])

# Превращаем в матрицу 2x3
reshaped = arr.reshape(2, 3)
print(reshaped)
# [[1 2 3]
#  [4 5 6]]

# Превращаем в матрицу 3x2
reshaped_2 = arr.reshape(3, 2)
print(reshaped_2)
# [[1 2]
#  [3 4]
#  [5 6]]

Совет: Общее количество элементов должно совпадать.

reshape() с -1

-1 означает «вычислить автоматически».

arr = np.array([1, 2, 3, 4, 5, 6])

# Автоматически вычисляем количество строк
reshaped = arr.reshape(2, -1)   # 2 строки, столбцы автоматически
print(reshaped)
# [[1 2 3]
#  [4 5 6]]

# Автоматически вычисляем количество столбцов
reshaped = arr.reshape(-1, 2)   # 2 столбца, строки автоматически
print(reshaped)
# [[1 2]
#  [3 4]
#  [5 6]]

Совет: -1 удобно, когда не хочется считать размеры вручную.

ravel() — преобразование в одномерный (view)

ravel() возвращает одномерный массив, создавая view (представление) исходного массива.

arr = np.array([[1, 2, 3], [4, 5, 6]])

# Превращаем в одномерный
raveled = arr.ravel()
print(raveled)   # [1 2 3 4 5 6]

# Изменяем raveled → меняется исходный массив
raveled[0] = 99
print(arr)       # [[99 2 3]
                 #  [4 5 6]]

Важно: ravel() создаёт view (представление). Изменение raveled меняет исходный массив.

flatten() — преобразование в одномерный (copy)

flatten() возвращает одномерный массив, создавая копию.

arr = np.array([[1, 2, 3], [4, 5, 6]])

# Превращаем в одномерный
flattened = arr.flatten()
print(flattened)   # [1 2 3 4 5 6]

# Изменяем flattened → исходный массив не меняется
flattened[0] = 99
print(arr)         # [[1 2 3]
                   #  [4 5 6]]

Совет: flatten() безопаснее, если не хочешь менять исходный массив.

ravel() vs flatten()

МетодВозвращаетПроизводительностьИзменяет исходный
ravel()view (представление)БыстрееДа
flatten()copy (копия)МедленнееНет
arr = np.array([[1, 2, 3], [4, 5, 6]])

# Проверяем, что это view
r = arr.ravel()
f = arr.flatten()

print(r.base is arr)   # True (view)
print(f.base is arr)   # False (copy)

Совет: Если нужно изменить данные — используй ravel(). Если нет — flatten().

reshape() vs resize()

reshape() возвращает новый массив с изменённой формой.

resize() изменяет исходный массив на месте.

arr = np.array([1, 2, 3, 4, 5, 6])

# reshape — создаёт новый массив
reshaped = arr.reshape(2, 3)
print(arr)         # [1 2 3 4 5 6] — не изменился
print(reshaped)    # [[1 2 3]
                   #  [4 5 6]]

# resize — изменяет исходный массив
arr.resize(2, 3)
print(arr)         # [[1 2 3]
                   #  [4 5 6]]

Совет: resize() меняет исходный массив, reshape() — нет.

Изменение формы многомерных массивов

arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr_3d.shape)   # (2, 2, 2)

# Превращаем в двумерный
reshaped = arr_3d.reshape(4, 2)
print(reshaped)
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# Превращаем в одномерный
flattened = arr_3d.flatten()
print(flattened)   # [1 2 3 4 5 6 7 8]

Полный пример

import numpy as np

# Создаём массив
arr = np.arange(12)
print("Исходный массив:", arr)

# reshape
reshaped = arr.reshape(3, 4)
print("reshape (3x4):\n", reshaped)

# reshape с -1
reshaped_auto = arr.reshape(-1, 3)
print("reshape (-1, 3):\n", reshaped_auto)

# ravel (view)
raveled = reshaped.ravel()
print("ravel:", raveled)

# flatten (copy)
flattened = reshaped.flatten()
print("flatten:", flattened)

# Изменяем raveled
raveled[0] = 99
print("После изменения raveled:")
print("reshaped:\n", reshaped)   # изменился
print("flattened:", flattened)   # не изменился

# Проверка, что ravel — view
print("ravel.base is reshaped:", raveled.base is reshaped)
print("flatten.base is reshaped:", flattened.base is reshaped)

Результат:

Исходный массив: [0 1 2 3 4 5 6 7 8 9 10 11]
reshape (3x4):
 [[0 1 2 3]
  [4 5 6 7]
  [8 9 10 11]]
reshape (-1, 3):
 [[0 1 2]
  [3 4 5]
  [6 7 8]
  [9 10 11]]
ravel: [0 1 2 3 4 5 6 7 8 9 10 11]
flatten: [0 1 2 3 4 5 6 7 8 9 10 11]
После изменения raveled:
reshaped:
 [[99 1 2 3]
  [4 5 6 7]
  [8 9 10 11]]
flattened: [0 1 2 3 4 5 6 7 8 9 10 11]
ravel.base is reshaped: True
flatten.base is reshaped: False

Задачи для закрепления

Задача 1. Измени форму массива из 12 элементов на 3×4.

Задача 2. Преврати двумерный массив в одномерный с помощью ravel().

Задача 3. Создай копию одномерного массива с помощью flatten().

Задача 4. Используй reshape(-1, 1) для превращения одномерного массива в вектор-столбец.

Задача 5. В чём разница между ravel() и flatten()?

Ответы:

Задача 1.

arr = np.arange(12)
reshaped = arr.reshape(3, 4)
print(reshaped)

Задача 2.

arr_2d = np.array([[1, 2], [3, 4]])
raveled = arr_2d.ravel()
print(raveled)   # [1 2 3 4]

Задача 3.

arr_2d = np.array([[1, 2], [3, 4]])
flattened = arr_2d.flatten()
print(flattened)   # [1 2 3 4]

Задача 4.

arr = np.array([1, 2, 3, 4])
col = arr.reshape(-1, 1)
print(col)
# [[1]
#  [2]
#  [3]
#  [4]]

Задача 5.

# ravel() — view (изменяет исходный массив)
# flatten() — copy (не изменяет исходный массив)

Нюансы и подводные камни

ravel() иногда возвращает копию

Если массив не является непрерывным в памяти, ravel() может вернуть копию.

reshape() не меняет порядок данных

Элементы читаются по строкам (C-стиль) по умолчанию.

Ошибка при несовпадении размеров

reshape() вызовет ошибку, если общее количество элементов не совпадает.

Частые ошибки и как их избежать

Ошибка 1: Несовпадение размеров

# Ошибка! 6 ≠ 8
arr = np.array([1, 2, 3, 4, 5, 6])
# arr.reshape(2, 4)   # ValueError

Ошибка 2: Изменение исходного массива через ravel()

Если не хочешь менять исходный — используй flatten().

Ошибка 3: Путаница между reshape() и resize()

reshape() — новый массив, resize() — изменяет исходный.

Шпаргалка

МетодЧто делаетВозвращаетМеняет исходный
reshape()Изменяет формуНовый массивНет
resize()Изменяет формуНовый массивДа
ravel()В одномерныйViewДа
flatten()В одномерныйCopyНет

Заключение

Сегодня мы:

  • Узнали, как изменять форму массивов
  • Изучили reshape()ravel()flatten()
  • Разобрали отличия между методами
  • Практические примеры

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×