[Numpy-discussion] storage for records

Travis Oliphant oliphant.travis at ieee.org
Sat Feb 18 17:21:10 CST 2006


Stefan van der Walt wrote:

>I am probably trying to do something silly, but still:
>
>In [1]: import numpy as N
>
>In [2]: N.__version__
>Out[2]: '0.9.6.2127'
>
>In [3]: P = N.array(N.zeros((2,2)), N.dtype((('f4',3), {'names': ['x','y','z'], 'formats': ['f4','f4','f4']})))
>*** glibc detected *** malloc(): memory corruption: 0x0830bb48 ***
>Aborted
>
>Regards
>Stéfan
>  
>
This code found a bug that's been there for a while in the 
PyArray_CastTo code (only seen on multiple copies) which is being done 
here as the 2x2 array of zeros is being cast to a 2x2x3 array of 
floating-point zeros.

The bug should be fixed in SVN, now.

Despite the use of fields, the base-type is ('f4',3) which is equivalent 
to (tack on a 3 to the shape of the array of 'f4').  So, on array 
creation the fields will be lost and you will get a 2x2x3 array of 
float32.   Types like ('f4', 3) are really only meant to be used in 
records.  If they are used "by themselves" they simply create an array 
of larger dimension.  

By the way,  the N.dtype in the array constructor is unnecessary as that 
is essentially what is done to the second argument anyway

You can get two different views of the same data (which it seems you are 
after) like this:

P = N.zeros((2,2), {'names': ['x','y','z'], 'formats': ['f4','f4','f4']})
Q = P.view(('f4',3))

Then

Q[...,0] = 10
print P['x']

If you want the field to vary in the first dimension, then you really 
want a FORTRAN array.  So,

P = N.zeros((2,2), {'names': ['x','y','z'], 'formats': 
['f4','f4','f4']},fortran=1)
Q = P.view(('f4',3))

Then

Q[0] = 20
print P['x']


Best,

-Travis










More information about the Numpy-discussion mailing list