<jupyter_start><jupyter_text>Numpy Copies and ViewsПри работе с массивами зачастую создаются не новые объекты, а их отображения или ссылки на тот же объект. Присваивание без копированияПример с присваиванием значения по индексу массива:<jupyter_code>import numpy as np
# Create an array
a = np.arange(6)
b = a    # no new object is created
a        # print a
a[0] = 9   # change one element
b          # b[0] has been changed too!<jupyter_output><empty_output><jupyter_text>В отличие от С++ в Python прямое присваивание массивов не создает новую копию! Вместо этого создается новая ссылка на объект *nparray* и значение *refcnt* увеличивается на 1.<jupyter_code>a is b
np.all(a == b)<jupyter_output><empty_output><jupyter_text>Идентификаторы объектов также равны!<jupyter_code>id(a) == id(b)<jupyter_output><empty_output><jupyter_text>Python передает изменяемые объекты в качестве *ссылок*, поэтому вызовы функций не создают локальных копий объектов.<jupyter_code>print(id(a))

def calc(x):
    print(id(x))

calc(a)   # id is a unique identifier of an object<jupyter_output>140487729739136
140487729739136<jupyter_text>Отображение (представление) или поверхностная копияРазные объекты могут совместно использовать одни и те же данные. Метод **view** создает новый массив (объект), который указывает на те же данные.<jupyter_code>c = a.view()
c<jupyter_output><empty_output><jupyter_text>В связи с этим, элементы массивов равны друг другу, но новый массив указывает на другое место<jupyter_code>np.all(b == a)
c is a
id(a) == id(c)<jupyter_output><empty_output><jupyter_text>Атрибуты *base* и *flags.owndata* нового массива:<jupyter_code>c.base is a  # c is a view of the data owned by a
c.flags.owndata<jupyter_output><empty_output><jupyter_text>При изменении **размерности** массива, оригинальный массив не меняется:<jupyter_code>c.shape = (2,3)  # a's shape doesn't change
c
a<jupyter_output><empty_output><jupyter_text>При изменении **значения** массива, оригинальный массив изменяется:<jupyter_code>c[0,0] = 7
a<jupyter_output><empty_output><jupyter_text>Замечание: метод **reshape** возвращает view, а если это невозможно - создает copy массива!<jupyter_code>a.reshape(3,2)   # view
a   # original array<jupyter_output><empty_output><jupyter_text>Таблица методов и возвращаемые значения:| N  | method        | return | description ||---:| -------------:| ---------------------------------------------:|---------------------------------:|| 1  | transpose     | view                                          | транспонирование матрицы         || 2  | reshape       | view, otherwise - copy                        | изменение размерности массива    || 3  | split         | list of subarrays (same as hsplit, vsplit)    | разбиение массива на подмассивы  || 4  | stack         | new array (same as hstack, vstack)            | слияние массивов                 || 5  | repeat        | new array                                     | повторение массива               || 6  | tile          | new array                                     | повторение массива               || 7  | ravel         | new array                                     | выравнивание массива вдоль оси   || 8  | concatenate   | new array                                     | объединение массивов             || 9  | resize        | new array, in-place change an old array       | изменение размерности массива    || 10 | flatten       | copy of the array                             | выравнивание массива             || 11 | flat          | A 1-D iterator over the array                 | итератор по одномерному массиву  |  Срезы массива Срезы возвращают отображение (view) на массив, а не его копию!<jupyter_code>s = a[:3]   # get three elements of 'a'
s[:] = 0    # set all elements = 0
s
a   # 'a' has been changed
a[-3:-1] = 1
a<jupyter_output><empty_output><jupyter_text>Копия (deep copy)Для создания полноценной копии массива используется одноименный метод **copy**<jupyter_code>a   # Old array
b = a.copy()   # Deep copy
b
a is b   # Objects aren't equal
b.flags.owndata    # New array with own data
b[:] = 9
b
a<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10933333333333334, 'fraction_numerical': 0.015272727272727273, 'mean_word_length': 2.7680365296803653, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '209768', 'license': 'MIT', 'n_tokens_mistral': 1537, 'n_tokens_neox': 1607, 'n_words': 391, 'path': 'numpy/numpy_view_copy.ipynb', 'repo_name': 'hukenovs/py-tutorial', 'size': '4125'}