From: Sebastien B. <Seb...@ob...> - 2006-10-20 09:42:40
|
Hi! I am confused with Numpy behavior with its scalar or 0-d arrays objects: >>> numpy.__version__ '1.0rc2' >>> a = numpy.array((1,2,3)) >>> b = a[:2] >>> b += 1 >>> b array([2, 3]) >>> a array([2, 3, 3]) >>> type(b) <type 'numpy.ndarray'> To this point all is ok for me: subarrays share (by default) memory with their parent array. But: >>> c = a[2] >>> c += 1 >>> c 4 >>> a array([2, 3, 3]) >>> type(c) <type 'numpy.int32'> >>> id(c) 169457808 >>> c += 1 >>> id(c) 169737448 That's really confusing, because slices (from __getslice__ method) are not copies (they share memory), and items (single elements from __getitem__ ) are copies to one of the scalar objects provided by Numpy. I can understand that numpy.scalars do not provide inplace operations (like Python standard scalars, they are immutable), so I'd like to use 0-d Numpy.ndarrays. But: >>> d = numpy.array(a[2],copy=False) >>> d += 1 >>> d array(4) >>> a array([2, 3, 3]) >>> type(d) <type 'numpy.ndarray'> >>> d.shape () >>> id(d) 169621280 >>> d += 1 >>> id(d) 169621280 This is not a solution because d is a copy since construction time... My question is: is there a way to get a single element of an array into a 0-d array which shares memory with its parent array? Thx for your help, Sebastien |
From: Francesc A. <fa...@ca...> - 2006-10-20 10:56:09
|
A Divendres 20 Octubre 2006 11:42, Sebastien Bardeau va escriure: [snip] > I can understand that numpy.scalars do not provide inplace operations > (like Python standard scalars, they are immutable), so I'd like to use > > 0-d Numpy.ndarrays. But: > >>> d =3D numpy.array(a[2],copy=3DFalse) > >>> d +=3D 1 > >>> d > > array(4) > > >>> a > > array([2, 3, 3]) > > >>> type(d) > > <type 'numpy.ndarray'> > > >>> d.shape > > () > > >>> id(d) > > 169621280 > > >>> d +=3D 1 > >>> id(d) > > 169621280 > > This is not a solution because d is a copy since construction time... > My question is: is there a way to get a single element of an array into > a 0-d array which shares memory with its parent array? One possible solution (there can be more) is using ndarray: In [47]: a=3Dnumpy.array([1,2,3], dtype=3D"i4") In [48]: n=3D1 # the position that you want to share In [49]: b=3Dnumpy.ndarray(buffer=3Da[n:n+1], shape=3D(), dtype=3D"i4") In [50]: a Out[50]: array([1, 2, 3]) In [51]: b Out[51]: array(2) In [52]: b +=3D 1 In [53]: b Out[53]: array(3) In [54]: a Out[54]: array([1, 3, 3]) Cheers, =2D-=20 >0,0< Francesc Altet =A0 =A0 http://www.carabos.com/ V V C=E1rabos Coop. V. =A0=A0Enjoy Data "-" |
From: Sebastien B. <Seb...@ob...> - 2006-10-20 13:25:59
|
> One possible solution (there can be more) is using ndarray: > > In [47]: a=numpy.array([1,2,3], dtype="i4") > In [48]: n=1 # the position that you want to share > In [49]: b=numpy.ndarray(buffer=a[n:n+1], shape=(), dtype="i4") > Ok thanks. Actually that was also the solution I found. But this is much more complicated when arrays are N dimensional with N>1, and above all if user asks for a slice in one or more dimension. Here is how I redefine the __getitem__ method for my arrays. Remember that the goal is to return a 0-d array rather than a numpy.scalar when I extract a single element out of a N-dimensional (N>=1) array: def __getitem__(self,index): # Index may be either an int or a tuple # Index length: if type(index) == int: # A single element through first dimension ilen = 1 index = (index,) # A tuple else: ilen = len(index) # Array rank: arank = len(self.shape) # Check if there is a slice: for i in index: if type(i) == slice: hasslice = True else: hasslice = False # Array is already a 0-d array: if arank == 0 and index == (0,): return self[()] elif arank == 0: raise IndexError, "0-d array has only one element at index 0." # This will return a single element as a 0-d array: elif arank == ilen and hasslice: # This ugly thing returns a numpy 0-D array AND NOT a numpy scalar! # (Numpy scalars do not share their data with the parent array) newindex = list(index) newindex[0] = slice(index[0],index[0]+1,None) newindex = tuple(newindex) return self[newindex].reshape(()) # This will return a n-D subarray (n>=1): else: return self[index] Well... I do not think this is very nice. Someone has another idea? My question in my first post was: is there a way to get a single element of an array into a 0-d array which shares memory with its parent array? Sebastien |
From: Sebastien B. <Seb...@ob...> - 2006-10-20 13:49:17
|
Ooops sorry there was two mistakes with the 'hasslice' flag. This seems now to work for me. def __getitem__(self,index): # Index may be either an int or a tuple # Index length: if type(index) == int: # A single element through first dimension ilen = 1 index = (index,) # A tuple else: ilen = len(index) # Array rank: arank = len(self.shape) # Check if there is a slice: hasslice = False for i in index: if type(i) == slice: hasslice = True # Array is already a 0-d array: if arank == 0 and index == (0,): return self elif arank == 0: raise IndexError, "0-d array has only one element at index 0." # This will return a single element as a 0-d array: elif arank == ilen and not hasslice: # This ugly thing returns a numpy 0-D array AND NOT a numpy scalar! # (Numpy scalars do not share their data with the parent array) newindex = list(index) newindex[0] = slice(index[0],index[0]+1,None) newindex = tuple(newindex) return self[newindex].reshape(()) # This will return a n-D subarray (n>=1): else: return self[index] Sebastien Bardeau wrote: >> One possible solution (there can be more) is using ndarray: >> >> In [47]: a=numpy.array([1,2,3], dtype="i4") >> In [48]: n=1 # the position that you want to share >> In [49]: b=numpy.ndarray(buffer=a[n:n+1], shape=(), dtype="i4") >> >> > Ok thanks. Actually that was also the solution I found. But this is much > more complicated when arrays are N dimensional with N>1, and above all > if user asks for a slice in one or more dimension. Here is how I > redefine the __getitem__ method for my arrays. Remember that the goal is > to return a 0-d array rather than a numpy.scalar when I extract a single > element out of a N-dimensional (N>=1) array: > > def __getitem__(self,index): # Index may be either an int or a tuple > # Index length: > if type(index) == int: # A single element through first dimension > ilen = 1 > index = (index,) # A tuple > else: > ilen = len(index) > # Array rank: > arank = len(self.shape) > # Check if there is a slice: > for i in index: > if type(i) == slice: > hasslice = True > else: > hasslice = False > # Array is already a 0-d array: > if arank == 0 and index == (0,): > return self[()] > elif arank == 0: > raise IndexError, "0-d array has only one element at index 0." > # This will return a single element as a 0-d array: > elif arank == ilen and hasslice: > # This ugly thing returns a numpy 0-D array AND NOT a numpy scalar! > # (Numpy scalars do not share their data with the parent array) > newindex = list(index) > newindex[0] = slice(index[0],index[0]+1,None) > newindex = tuple(newindex) > return self[newindex].reshape(()) > # This will return a n-D subarray (n>=1): > else: > return self[index] > > Well... I do not think this is very nice. Someone has another idea? My > question in my first post was: is there a way to get a single element of > an array into > a 0-d array which shares memory with its parent array? > > Sebastien > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Numpy-discussion mailing list > Num...@li... > https://lists.sourceforge.net/lists/listinfo/numpy-discussion > > > -- ------------------------- Sebastien Bardeau L3AB - CNRS UMR 5804 2 rue de l'observatoire BP 89 F - 33270 Floirac Tel: (+33) 5 57 77 61 46 ------------------------- |
From: Tim H. <tim...@ie...> - 2006-10-20 14:17:47
|
Sebastien Bardeau wrote: > Ooops sorry there was two mistakes with the 'hasslice' flag. This seems > now to work for me. > > [SNIP code] That looks overly complicated. I believe that this (minimally tested in a slightly different setting) or some variation should work: return self[...,newaxis][index].reshape(self[index].shape) -tim |
From: Tim H. <tim...@ie...> - 2006-10-20 13:45:16
|
Francesc Altet wrote: > A Divendres 20 Octubre 2006 11:42, Sebastien Bardeau va escriure: > [snip] > >> I can understand that numpy.scalars do not provide inplace operations >> (like Python standard scalars, they are immutable), so I'd like to use >> >> 0-d Numpy.ndarrays. But: >> >>> d = numpy.array(a[2],copy=False) >> >>> d += 1 >> >>> d >> >> array(4) >> >> >>> a >> >> array([2, 3, 3]) >> >> >>> type(d) >> >> <type 'numpy.ndarray'> >> >> >>> d.shape >> >> () >> >> >>> id(d) >> >> 169621280 >> >> >>> d += 1 >> >>> id(d) >> >> 169621280 >> >> This is not a solution because d is a copy since construction time... >> My question is: is there a way to get a single element of an array into >> a 0-d array which shares memory with its parent array? >> > > One possible solution (there can be more) is using ndarray: [SNIP] Here's a slightly more concise version of the same idea: b = a[n:n+1].reshape([]) -tim |
From: Stefan v. d. W. <st...@su...> - 2006-10-20 13:22:53
|
On Fri, Oct 20, 2006 at 11:42:26AM +0200, Sebastien Bardeau wrote: > >>> a =3D numpy.array((1,2,3)) > >>> b =3D a[:2] Here you index by a slice. > >>> c =3D a[2] Whereas here you index by a scalar. So you want to do b =3D a[[2]] b +=3D 1 or in the general case b =3D a[slice(2,3)] b +=3D 1 Regards St=E9fan |
From: Travis O. <oli...@ee...> - 2006-10-20 23:13:04
|
Sebastien Bardeau wrote: >>One possible solution (there can be more) is using ndarray: >> >>In [47]: a=numpy.array([1,2,3], dtype="i4") >>In [48]: n=1 # the position that you want to share >>In [49]: b=numpy.ndarray(buffer=a[n:n+1], shape=(), dtype="i4") >> >> >> >Ok thanks. Actually that was also the solution I found. But this is much >more complicated when arrays are N dimensional with N>1, and above all >if user asks for a slice in one or more dimension. Here is how I >redefine the __getitem__ method for my arrays. Remember that the goal is >to return a 0-d array rather than a numpy.scalar when I extract a single >element out of a N-dimensional (N>=1) array: > > How about this. To get the i,j,k,l element a[i:i+1,j:j+1,k:k+1,l:l+1].squeeze() -Travis |
From: Lisandro D. <da...@gm...> - 2006-10-21 23:26:48
|
On 10/20/06, Travis Oliphant <oli...@ee...> wrote: > > How about this. To get the i,j,k,l element > > a[i:i+1,j:j+1,k:k+1,l:l+1].squeeze() > > -Travis I think all this can be condensed in a method call or similar mehcanism, natively provided by ndarray type. Or should this be seen as a special use case? --=20 Lisandro Dalc=EDn --------------- Centro Internacional de M=E9todos Computacionales en Ingenier=EDa (CIMEC) Instituto de Desarrollo Tecnol=F3gico para la Industria Qu=EDmica (INTEC) Consejo Nacional de Investigaciones Cient=EDficas y T=E9cnicas (CONICET) PTLC - G=FCemes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594 |