Подтвердить что ты не робот

Numpy, массив не имеет собственных данных?

Я попытался использовать resize в массиве следующим образом:

a = np.array([1,2,3,4,5,6], dtype=np.uint8)
a.resize(4,2)
print a 

и выход Ok! (я имел в виду, что ошибки не было). Но когда я запускаю этот код:

a = np.array([1,2,3,4,5,6], dtype=np.uint8).reshape(2,3)
a.resize(4,2)
print a 

это породило ошибку, сказав, что ValueError: cannot resize this array: it does not own its data

Мой вопрос: почему после применения reshape изменилось право собственности на массив? Владение предоставляется кому!? reshape не создает новую память и выполняет ее работу в той же памяти массива! Итак, почему право собственности изменится?

Я читаю np.reshape и ndarray.resize doc, но я не могу понять причину. Я прочитал этот пост. Я всегда могу проверить ndarray.flags перед применением метода resize.

4b9b3361

Ответ 1

Давайте начнем со следующего:

>>> a = np.array([1,2,3,4,5,6], dtype=np.uint8)
>>> b = a.reshape(2,3)
>>> b[0,0] = 5
>>> a
array([5, 2, 3, 4, 5, 6], dtype=uint8)

Я вижу здесь, что массив b не является его собственным массивом, а просто представлением a (просто еще один способ понять флаг OWNDATA). Проще говоря, оба a и b ссылаются на одни и те же данные в памяти, но b просматривает a с другой формой. Вызов функции resize, такой как ndarray.resize, пытается изменить массив на месте, поскольку b - это просто представление a, это недопустимо, как из определения resize:

Цель проверки счетчика ссылок - убедиться, что вы не используете этот массив в качестве буфера для другого объекта Python и затем перераспределите память.


Чтобы обойти проблему, вы можете вызвать resize из numpy (а не как атрибут ndarray), который обнаружит эту проблему и скопирует данные автоматически:

>>> np.resize(b,(4,2))
array([[5, 2],
       [3, 4],
       [5, 6],
       [5, 2]], dtype=uint8)

Изменить: Поскольку CT Zhu правильно упоминает np.resize и ndarray.resize, добавьте данные двумя разными способами. Чтобы воспроизвести ожидаемое поведение как ndarray.resize, вам нужно будет сделать следующее:

>>> c = b.copy()
>>> c.resize(4,2)
>>> c
array([[5, 2],
       [3, 4],
       [5, 6],
       [0, 0]], dtype=uint8)