对不存在的数组使用 numpy 视图
Posted
技术标签:
【中文标题】对不存在的数组使用 numpy 视图【英文标题】:Using a numpy view to a non-existing array 【发布时间】:2018-01-25 14:45:32 【问题描述】:在定义一个带零的数组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 能正确处理它,如果是,为什么不抛出错误?
【问题讨论】:
引用计数。原始对象a
仍然存在,因为它被视图引用。 (虽然不能再通过变量a
访问。)
【参考方案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
访问。
【讨论】:
有趣。那么在视图的情况下,我必须自己做内存管理? @Chiel 不,这都是自动的。虽然存在数组中的视图,但它们算作对对象的引用。当一个对象不再被引用(不再有视图或其他引用)时,它会在某个时候被垃圾收集器删除。 我明白了,但是由于我倾向于为快捷方式创建很多视图,这意味着我必须明确删除所有视图,以便恢复记忆。对吗? @Chiel 没错。但是,这通常只是变量存在的长脚本中的问题。当函数返回时,所有作为局部变量存在的视图都将被删除;如果您重新分配一个变量(例如,在循环中),您也不必显式删除它。【参考方案2】:行为不是未定义的。您只是在创建一个新对象a
。旧的没有被释放,但仍然存在于内存中,因为 a_left_col 仍然引用它。一旦你重新初始化a_left_col
,原始数组就可以被释放了。
【讨论】:
以上是关于对不存在的数组使用 numpy 视图的主要内容,如果未能解决你的问题,请参考以下文章
destoon对不起,您查找的页面不存在,以下信息有没有您需要的?