NumPy view и copy: почему срез меняет исходный массив
Обычный срез массива NumPy обычно создаёт view: новое представление использует память исходного массива. Изменение такого среза меняет соответствующие элементы исходного массива.
Когда нужна независимая копия
Выражение a[1:3] использует базовую индексацию и разделяет данные с a. Вызов .copy() создаёт независимые данные. Для проверки общей памяти используйте np.shares_memory, а не равенство значений массивов.
Чтение через целочисленный список индексов или булеву маску создаёт копию. При этом присваивание a[mask] = value всё равно меняет a: здесь индексируется объект, в который записывается новое значение. Эти правила относятся к ndarray NumPy.
Пример на других данных
import numpy as np
a = np.array([10, 20, 30, 40])
view = a[1:3]
copy = a[1:3].copy()
view[0] = 99
print(a.tolist())
print(copy.tolist())
print(np.shares_memory(a, view), np.shares_memory(a, copy))
Результат:
[10, 99, 30, 40]
[20, 30]
True False
Попробуйте сами
Ниже — отдельное упражнение: напишите код и запустите проверку. Другие упражнения по этой теме. Для обучения по порядку откройте бесплатный курс NumPy и pandas.
View и copy на столбцовом срезе двумерного массива: изоляция мутации
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая демонстрирует разницу между view и copy на двумерном массиве:
- Читает из
stdinдва целых числаRиC— число строк и столбцов. - Читает следующие
Rстрок; каждая содержит ровноCцелых чисел через пробел. Создаёт двумерный массивMчерезnp.array(..., dtype=int)формы(R, C). - Читает одну строку с двумя целыми числами
r0иr1— границы среза строк. - Читает одну строку с двумя целыми числами
mrowиmcol— позиция для мутации внутри среза (индексы относительно среза). - Читает одно целое число
val— новое значение. - Получает view
vw = M[r0:r1, :]и копиюcp = M[r0:r1, :].copy(). - Выводит строку
shares_vw=<True|False>— результатnp.shares_memory(M, vw). - Выводит строку
shares_cp=<True|False>— результатnp.shares_memory(M, cp). - Выполняет
vw[mrow, mcol] = val. Выводит строкуM_after_vw=<строки M через ; каждая строка — значения через пробел>. - Выполняет
cp[mrow, mcol] = val. Выводит строкуM_after_cp=<строки M через ; каждая строка — значения через пробел>.
Строки матрицы в выводе разделяются символом ;, значения внутри строки — пробелом.
Ввод и вывод
Программа читает stdin и пишет в stdout.
Формат ввода
R C
<R строк по C целых чисел через пробел>
r0 r1
mrow mcol
val
Гарантируется: 0 <= r0 < r1 <= R, 0 <= mrow < r1 - r0, 0 <= mcol < C.
Формат вывода
shares_vw=<True|False>
shares_cp=<True|False>
M_after_vw=<строки через ;>
M_after_cp=<строки через ;>
Пример
- Ввод
3 4 1 2 3 4 5 6 7 8 9 10 11 12 0 2 1 2 99
- Вывод
shares_vw=True shares_cp=False M_after_vw=1 2 3 4; 5 6 99 8; 9 10 11 12 M_after_cp=1 2 3 4; 5 6 99 8; 9 10 11 12
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- View и copy: предсказание влияния изменений среза на исходный массив — задача по NumPy и pandas
- NumPy sharesmemory: view, copy и изменение исходного массива
- dtype NumPy: целые и вещественные массивы, типы элементов
- NumPy shape, ndim, size и dtype: атрибуты массива и задача
- Срезы двумерного массива NumPy: строки, столбцы и шаг
- NumPy reshape и transpose: разница на примере и задача
