将numpy视图用于不存在的数组

时间:2018-01-25 14:45:33

标签: python numpy view

使用零定义arrray a后,我可以使用以下函数创建最左侧列的视图:

a = np.zeros((5, 5))
a_left_col = a[:, 0]

a_left_col[:] = 2.

打印a

array([[2., 0., 0., 0., 0.],
       [2., 0., 0., 0., 0.],
       [2., 0., 0., 0., 0.],
       [2., 0., 0., 0., 0.],
       [2., 0., 0., 0., 0.]])

如果我随后使用

重新初始化a
a = np.zeros((5, 5))

然后视图仍然存在,但它不再引用任何内容。如果再次执行a_left_col[:] = 2,Python如何处理这种情况?这是在C或C ++中的未定义行为,还是Python正确处理它,如果是这样,为什么不抛出错误?

2 个答案:

答案 0 :(得分:1)

行为未定义。您只是在创建一个新对象a。旧的不会被释放,但仍然存在于内存中,因为a_left_col仍然引用它。重新初始化a_left_col后,可以取消分配原始数组。

答案 1 :(得分:1)

原始对象仍然存在,因为它被视图引用。 (虽然不能再通过变量a访问它。)

让我们详细了解一下对象的引用计数:

import sys
import numpy as np

a = np.zeros((5, 5))
print(sys.getrefcount(a))  # 2

a_left_col = a[:, 0]
print(sys.getrefcount(a))  # 3
print(sys.getrefcount(a_left_col.base))  # 3
print(a_left_col.base is a)  # True

a = np.ones((5, 5))
print(sys.getrefcount(a_left_col.base))  # 2

请注意a_left_col.base是对原始数组的引用。当我们重新a时,对象的引用计数会减少,但它仍然存在,因为它是可以访问的a_left_col