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

If I call y = foo() I'll get a 5x5 array (1/4 of the values in x). But what happens to the other values in x, do they persist in memory or get garbage collected in some way? I'd like to understand this.

Nic
  • 637
  • 2
  • 6
  • 19
  • 1
    Possibly a useful read: [Python garbage collector documentation](https://stackoverflow.com/questions/4484167/python-garbage-collector-documentation/4484312) – pault Apr 24 '18 at 20:09
  • 2
    Basic slicing of a NumPy array creates a view of the array ,which retains a reference to the original array. The original array must be kept around for the slice to make any sense. The array named `x` will stick around as long as its slice view does. See https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html – kindall Apr 24 '18 at 20:10
  • @kindall do you have a reference on that? I'm not very familiar with numpy internals and would be interested in learning more – Chrispresso Apr 24 '18 at 20:12
  • 1
    The link I posted outlines basic vs. advanced indexing, and notes that basic indexing creates a view. – kindall Apr 24 '18 at 20:21

1 Answers1

3

As kindall says in the comments, basic slicing on a NumPy array creates a view of the original array. The view has to keep the entire original object alive; you can see the reference it uses to do so in the view's base attribute.

In [2]: x = numpy.ones((10, 10))

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

In [4]: y.base is x
Out[4]: True
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • 4
    Worth noting that `y = y.copy()` will cause `x` to be cleaned up – Eric Apr 24 '18 at 22:38
  • Even if x goes out of scope? – Nic Apr 25 '18 at 03:23
  • @Nic: Object lifetimes have no scope. Variables have scope, but variables are not objects. – user2357112 Apr 25 '18 at 03:37
  • Isn't `x` a variable that points to the ndarray? When `x` goes out of scope doesn't the garbage collector call some kind of dispose function on it? That's my question - is the entire ndarray preserved because of `y`? – Nic Apr 25 '18 at 07:39
  • 2
    Yes, the entire array is preserved because of `y`. The garbage collector isn't involved here; this is a simple case of reference counting. `x` is a reference to the array, and `y` is a view which contains a reference to the array. When `x` goes away, there's still a reference somewhere within `y`. The array isn't disposed of until its reference count is zero, which it's not. If `y` goes out of scope, though, the view will be disposed of, which will allow the array to be disposed of. – kindall Apr 25 '18 at 13:50