[Numpy-discussion] ndarray.resize method and reference counting
Jon Olav Vik
jonovik at gmail.com
Sat Jan 31 12:59:47 EST 2009
Scott Sinclair <scott.sinclair.za <at> gmail.com> writes:
> >>> import numpy as np
> >>> x = np.eye(3)
> >>> x
> array([[ 1., 0., 0.],
> [ 0., 1., 0.],
> [ 0., 0., 1.]])
> >>> x.resize((5,5))
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ValueError: cannot resize an array that has been referenced or is referencing
> another array in this way. Use the resize function
I'm having the same problem, and have resigned to using "x = resize(x,
newshape)" rather than "x.resize(newshape)" as suggested in the error message.
Anything else becomes almost impossible to debug. Basically, you must never
step into a function that does x.resize().
Part of the reason is explained here:
http://article.gmane.org/gmane.comp.python.numeric.general/5461
In my experience, reference counting behaves differently between:
* non-interactive running and simple IPython "run" of scripts (works as
intended)
* interactive entering of commands in IPython (entering "x" at prompt "In [n]"
defines an alias _n)
* debugging with "run -d" in Python (symbols in inner scopes seem to get extra
references to them)
See the example below (using IPython 0.8.1/Python 2.5.2/Numpy 1.1.0/Linux) for
illustration.
Hope this helps,
Jon Olav
====
In [10]: cat test.py
import numpy, sys
x = numpy.zeros(3)
print sys.getrefcount(x)
x.resize(2)
x
print sys.getrefcount(x)
x.resize(1)
def test():
y = numpy.zeros(3)
print sys.getrefcount(y)
y.resize(2)
y
print sys.getrefcount(y)
y.resize(1)
test()
In [11]: run test.py
2
2
2
2
=====
Non-interactively, getrefcount() returns 2 on all four occasions. Entering the
same commands interactively, the refcount of x increases by 4 on entering "x"
at the prompt. Inside a function call there is no problem, though.
=====
In [2]: import numpy, sys
In [3]: x = numpy.zeros(3)
In [4]: print sys.getrefcount(x)
2
In [5]: x.resize(2)
In [6]: x
Out[6]: array([ 0., 0.])
In [7]: print sys.getrefcount(x)
6
In [8]: x.resize(1)
---------------------------------------------------------------------------
<type 'exceptions.ValueError'>: cannot resize an array that has been referenced
or is referencing another array in this way. Use the resize function
In [9]: def test():
...: y = numpy.zeros(3)
...: print sys.getrefcount(y)
...: y.resize(2)
...: y
...: print sys.getrefcount(y)
...: y.resize(1)
...:
In [10]: test()
2
2
=====
When debugging, however, the x.resize() works fine, while the y.resize() inside
the test() function fails. (A workaround is to step over the function call,
using "n" rather than "s" in line 19.)
====
In [5]: run -d test.py
ipdb> s
1---> 1 import numpy, sys
----> 3 x = numpy.zeros(3)
----> 4 print sys.getrefcount(x)
2
----> 5 x.resize(2)
----> 6 x
----> 7 print sys.getrefcount(x)
2
----> 8 x.resize(1)
---> 10 def test():
---> 19 test()
ipdb> s
---> 10 def test():
---> 11 y = numpy.zeros(3)
---> 12 print sys.getrefcount(y)
3
---> 13 y.resize(2)
ValueError: 'cannot resize an array that has been referenced or is referencing
\nanother array in this way. Use the resize function'
=====
More information about the NumPy-Discussion
mailing list