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 на двумерном массиве:

  1. Читает из stdin два целых числа R и C — число строк и столбцов.
  2. Читает следующие R строк; каждая содержит ровно C целых чисел через пробел. Создаёт двумерный массив M через np.array(..., dtype=int) формы (R, C).
  3. Читает одну строку с двумя целыми числами r0 и r1 — границы среза строк.
  4. Читает одну строку с двумя целыми числами mrow и mcol — позиция для мутации внутри среза (индексы относительно среза).
  5. Читает одно целое число val — новое значение.
  6. Получает view vw = M[r0:r1, :] и копию cp = M[r0:r1, :].copy().
  7. Выводит строку shares_vw=<True|False> — результат np.shares_memory(M, vw).
  8. Выводит строку shares_cp=<True|False> — результат np.shares_memory(M, cp).
  9. Выполняет vw[mrow, mcol] = val. Выводит строку M_after_vw=<строки M через ; каждая строка — значения через пробел>.
  10. Выполняет 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
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи