Numpy:切片后的垃圾回收

5
def foo():
    x = np.ones((10,10))
    return x[:5,:5]

如果我调用y = foo(),我将得到一个5x5的数组(x中值的1/4)。但是x中的其他值会发生什么,它们会在内存中保留还是以某种方式被垃圾回收?我想要理解这个问题。

1
可能是一个有用的阅读:Python垃圾回收器文档 - pault
2
NumPy 数组的基本切片创建一个数组视图,该视图保留对原始数组的引用。为了使切片有任何意义,必须保留原始数组。只要它的切片视图存在,名为“x”的数组将保留存在。请参见 https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html。 - kindall
@kindall 你有相关的参考资料吗?我对NumPy的内部机制并不是很熟悉,希望了解更多。 - Chrispresso
1
我贴出的链接概述了基本索引与高级索引之间的区别,并指出基本索引创建了一个视图。 - kindall
1个回答

3
正如kindall在评论中所说,对NumPy数组进行基本切片会创建原始数组的视图。该视图必须保持整个原始对象的存在;您可以在视图的base属性中看到它用于此目的的引用。
In [2]: x = numpy.ones((10, 10))

In [3]: y = x[:5, :5]

In [4]: y.base is x
Out[4]: True

4
值得注意的是,y = y.copy()会导致清理x - Eric
即使x超出范围? - Nic
@Nic:对象的生命周期没有作用域。变量有作用域,但变量不是对象。 - user2357112
“x”不是指向ndarray的变量吗?当“x”超出范围时,垃圾收集器会调用某种处理函数吗?这就是我的问题——整个ndarray是否因为“y”的存在而得以保留? - Nic
2
是的,整个数组因为 y 被保留。垃圾收集器在这里没有起作用;这是一个简单的引用计数案例。x 是数组的引用,而 y 是包含对数组引用的视图。当 x 消失时,在 y 中仍然存在某处引用。直到其引用计数为零(现在不是),数组才被处理。但是,如果 y 超出范围,则将处理该视图,从而允许处理数组。 - kindall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接