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

Как я могу узнать, создает ли NumPy представление или копию?

Для минимального рабочего примера оцифруйте 2D-массив. numpy.digitize требуется массив 1D:

import numpy as np
N = 200
A = np.random.random((N, N))
X = np.linspace(0, 1, 20)
print np.digitize(A.ravel(), X).reshape((N, N))

Теперь документация:

... Копия делается только при необходимости.

Как узнать, нужна ли в этом случае копия ravel "нужна"? В общем - есть ли способ, который я могу определить, создает ли конкретная операция копию или представление?

4b9b3361

Ответ 1

Этот вопрос очень похож на вопрос который я попросил некоторое время назад:

Вы можете проверить атрибут base.

a = np.arange(50)
b = a.reshape((5, 10))
print (b.base is a)

Однако это не идеально. Вы также можете проверить, используют ли они память с помощью np.may_share_memory.

print (np.may_share_memory(a, b))

Также есть атрибут flags, который вы можете проверить:

print (b.flags['OWNDATA'])  #False -- apparently this is a view
e = np.ravel(b[:, 2])
print (e.flags['OWNDATA'])  #True -- Apparently this is a new numpy object.

Но этот последний кажется мне немного подозрительным, хотя я не могу сказать, почему...

Ответ 2

В документации для reshape есть информация о том, как обеспечить исключение, если представление не может быть выполнено:

Невозможно изменить форму массива без копирования данных. Если вы хотите, чтобы ошибка была повышена, если данные были скопированы, вы должны назначить новую форму атрибуту shape массива:

>>> a = np.zeros((10, 2))
# A transpose make the array non-contiguous
>>> b = a.T
# Taking a view makes it possible to modify the shape without modiying the
# initial object.
>>> c = b.view()
>>> c.shape = (20)
AttributeError: incompatible shape for a non-contiguous array




Это не совсем ответ на ваш вопрос, но в некоторых случаях это может быть так же полезно.