80

对于一个最小的工作示例,让我们数字化一个 2D 数组。numpy.digitize需要一维数组:

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它是否“需要”副本?一般来说 - 有没有一种方法可以确定特定操作是创建副本还是视图?

4

2 回答 2

86

这个问题与我不久前提出的一个问题非常相似:

您可以检查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.

但是最后一个对我来说似乎有点可疑,虽然我不能完全弄清楚为什么......

于 2012-07-17T14:30:03.857 回答
21

reshape的文档中,有一些关于如何在无法创建视图时确保异常的信息:

在不复制数据的情况下,并非总是可以更改数组的形状。如果要在复制数据时引发错误,则应将新形状分配给数组的形状属性:

>>> 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



这不完全是您问题的答案,但在某些情况下它可能同样有用。

于 2013-01-11T03:40:59.530 回答