2

I want a collection of all numpy arrays currently managed by my Python interpreter. Previous answers suggest that gc.get_objects() should do this for me. However I don't get expected results:

In [1]: import numpy as np

In [2]: import gc

In [3]: x = np.ones(5)

In [4]: any(item is x for item in gc.get_objects())
Out[4]: False

Is there a way to get all of the known NumPy arrays (or objects of any type really) currently instantiated?

MRocklin
  • 52,252
  • 21
  • 144
  • 218
  • For reference, from Jim Crist internal communication at Continuum Analytics: This explains why gc.get_objects doesn't work: https://mail.scipy.org/pipermail/numpy-discussion/2014-September/071186.html Numpy contains a tool for tracking allocations as a context manager. This plus a `WeakSet` could possibly help solve your problem. https://github.com/numpy/numpy/tree/master/tools/allocation_tracking – kalefranz May 05 '16 at 05:33

3 Answers3

2

This isn't a perfect answer, but according to this stackoverflow post you can use locals() to get a dictionary of all of the locally declared variables.

You can then get all of the known NumPy arrays using simple dict comprehension:

import numpy as np
np_arrays = {k:v for k,v in locals().items() if isinstance(v, np.ndarray)}

You can then iterate over the dictionary however you like after that.

Community
  • 1
  • 1
TheF1rstPancake
  • 2,150
  • 17
  • 17
1

I'm not sure if this addresses the exact problem you're trying to solve, but what about using locals()? That gets you started on at least getting what vars are being kept track of by the interpreter of your current interactive session?

import numpy as np
a = np.array([1, 2, 3])
b = np.array([2, 3, 4])
filter(lambda x : isinstance(x, np.ndarray), locals().values())
Thtu
  • 1,832
  • 14
  • 21
0

You can find numpy arrays with gc.get_objects() if you expand the objects recursively, as explained here

# code from https://utcc.utoronto.ca/~cks/space/blog/python/GetAllObjects
import gc
# Recursively expand slist's objects
# into olist, using seen to track
# already processed objects.
def _getr(slist, olist, seen):
  for e in slist:
    if id(e) in seen:
      continue
    seen[id(e)] = None
    olist.append(e)
    tl = gc.get_referents(e)
    if tl:
      _getr(tl, olist, seen)

# The public function.
def get_all_objects():
  """Return a list of all live Python
  objects, not including the list itself."""
  gcl = gc.get_objects()
  olist = []
  seen = {}
  # Just in case:
  seen[id(gcl)] = None
  seen[id(olist)] = None
  seen[id(seen)] = None
  # _getr does the real work.
  _getr(gcl, olist, seen)
  return olist

Now we should be able to find most objects

import numpy as np
import gc

x = np.ones(5)
objects = get_all_objects()
print(any([obj is x for obj in objects]))
# will return True, the np.ndarray is found!
skjerns
  • 1,463
  • 13
  • 22