Как я могу узнать, создает ли 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
"нужна"? В общем - есть ли способ, который я могу определить, создает ли конкретная операция копию или представление?
Ответы
Ответ 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
Это не совсем ответ на ваш вопрос, но в некоторых случаях это может быть так же полезно.