[Numpy-discussion] numarray __copy__ and __deepcopy__

Tim Hochberg tim.hochberg at ieee.org
Fri Nov 7 14:07:19 EST 2003


Fernando Perez wrote:

> Tim Hochberg wrote:
>
>> It appears that numarray.NumArray does not supply __copy__ or 
>> __deepcopy__ methods and as a result copy.copy and copy.deepcopy do 
>> not work correctly. It appears that adding "__copy__ = copy" to class 
>> NumArray is suffcient for copy, __deepcopy__ appears to need 
>> something more. Sadly, I don't have time to investigate this further 
>> right now.
>
>
> As far as I understand, this isn't really necessary with 
> Numeric/Numarray, because the copy() method in a sense always 
> guarantees a 'deep copy'.  Even when you make assignments to slices of 
> an array, the issue of nested structures which for python lists/dicts 
> requires deepcopy() just does not arise.  A simple illustration:

Your correct that anArray.copy() provides a deep copy of an array in 
both Numeric and numarray. However, you would like to be able to pass 
some object to copy.copy or copy.deepcopy and have it provide the 
appropriate type of copy whether the given object is an array, list or 
something other. I believe that in Numeric, copy.copy and copy.deepcopy 
do the right thing already. However, in numarray::

 >>> import copy, numarray as na
 >>> a = na.arange(3)
 >>> a
array([0, 1, 2])
 >>> b = copy.copy(a)
 >>> b[1] = 99
 >>> a
array([ 0, 99,  2]) # Urkh!

If you apply the fix I posted above that fixes copy.copy, but 
copy.deepcopy then fails. A full fix appears to be to add::
*
    def __copy__(self):
        return self.copy()
    def __deepcopy__(self, memo):
        return self.copy()

to Numarray. Then we get the desired behaviour:

*>>> import copy, numarray as na
 >>> a = na.arange(3)
 >>> b = copy.copy(a)
 >>> c = copy.deepcopy(a)
 >>> a[0] = 99
 >>> a, b, c
(array([99,  1,  2]), array([0, 1, 2]), array([0, 1, 2]))

It may be possible to get the same effect by tweaking __getstate__ and 
__setstate__, since they also can be used to control copying, but I'm 
not familar with those functions.

Regards,

-tim

>
>
> In [1]: a=arange(10)
>
> In [2]: b=arange(10,20)
>
> In [3]: c=arange(20,30)
>
> In [4]: d=zeros(30)
>
> In [5]: d[0:10] = a
>
> In [6]: d[10:20] = b
>
> In [7]: d[20:30] = c
>
> In [8]: a
> Out[8]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>
> In [9]: b
> Out[9]: array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>
> In [10]: c
> Out[10]: array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
>
> In [11]: d
> Out[11]:
> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 
> 16, 17, 18,
>             19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
>
> In [12]: b[:]=99
>
> In [13]: b
> Out[13]: array([99, 99, 99, 99, 99, 99, 99, 99, 99, 99])
>
> In [14]: d
> Out[14]:
> array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 
> 16, 17, 18,
>             19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29])
>
>
> Perhaps I'm missing some usage case, but I've always just used 
> ARR.copy() when I've needed a 'full copy' of an array.  This 
> guarantees that the returned array is contiguous (has .flat) and a 
> standalone copy of the data in ARR, regardless of the contiguity 
> properties of ARR.
>
> HTH.
>
> Cheers,
>
> f
>
> ps: my experience is actually from Numeric, I don't know if Numarray 
> differs in its copy() behavior.
>
>







More information about the NumPy-Discussion mailing list