Best representation for array of points, or, how to distinguish a Nx1 array of points from a Nx3 array of scalars
![](https://secure.gravatar.com/avatar/6036618d1313b418a1c464e2f24f1018.jpg?s=120&d=mm&r=g)
I've found that there are two ways to represent an array of 3D points: # 01: N = 4 a = numpy.zeros((N, 3), dtype='f8') # 02: N = 4 b = numpy.zeros(N, dtype='3f8') The second representation seems "conceptually" better, it is really an 1D array of N elements ( i.e., b.shape == (4,) ), but, "in practice", it is not very useful, because I can't directly add it to scalar, or to another array of points, and I can't multiply it by a transformation matrix. With the first representation, I can use expressions like this: c = (a+1) * numpy.matrix([[1,0,0],[0,0,3],[0,2,0]]) - numpy.array([1, 5.5, 0]) So, I chose the second representation for my application; the problem is that its shape is (N, 3), and I haven't found a way to distinguish it from a Nx3 array of scalars, for example. This distinction is needed, because I must convert it to other array types (from other libraries), I must make proper I/O of the array, etc. Also, my application uses 2D and 3D arrays, and they can be arrays of scalars, of points or of small matrices... so, for example, a 10x7 array of 2x2 matrices of double is represented in numpy as a 10x7x2x2 array of f8 (without the proper information, it could be viewed also as a 10x7x2 array of 2D points or a 10x7x2x2 array of doubles, and I DON'T want this). My question is: * Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above? Thanks, Edson
![](https://secure.gravatar.com/avatar/39916bae984cb93b797efd2b175f59c0.jpg?s=120&d=mm&r=g)
On Thu, 4 Oct 2007, Edson Tadeu apparently wrote:
Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above?
Perhaps you want a recarray? Cheers, Alan Isaac
![](https://secure.gravatar.com/avatar/764323a14e554c97ab74177e0bce51d4.jpg?s=120&d=mm&r=g)
Alan G Isaac wrote:
On Thu, 4 Oct 2007, Edson Tadeu apparently wrote:
Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above?
Perhaps you want a recarray?
No, that's what the dtype='3f8' gets him. He gave reasons why he doesn't want that. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
![](https://secure.gravatar.com/avatar/764323a14e554c97ab74177e0bce51d4.jpg?s=120&d=mm&r=g)
Edson Tadeu wrote:
* Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above?
There isn't. You could make a subclass that tracks this, but you would have to implement it carefully to maintain the information. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
![](https://secure.gravatar.com/avatar/af6c39d6943bd4b0e1fde23161e7bb8c.jpg?s=120&d=mm&r=g)
On Thu, Oct 04, 2007 at 11:47:40AM -0500, Robert Kern wrote:
Edson Tadeu wrote:
* Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above?
There isn't. You could make a subclass that tracks this, but you would have to implement it carefully to maintain the information.
There is an example of how to do that here: http://www.scipy.org/Subclasses Regards Stéfan
![](https://secure.gravatar.com/avatar/6036618d1313b418a1c464e2f24f1018.jpg?s=120&d=mm&r=g)
For now, I solved it using a view with a different type: from numpy import * N = 5 a=zeros(N,'3f8') b=a.view() b.dtype='f8' b.shape = N,3 I'll try to put this mechanism in a subclass. Thanks for the answers, Edson On 10/4/07, Stefan van der Walt <stefan@sun.ac.za> wrote:
On Thu, Oct 04, 2007 at 11:47:40AM -0500, Robert Kern wrote:
Edson Tadeu wrote:
* Is there any field in the NumPy object where I can keep this information (the shape of the "element"), without creeping it with the dtype='(M,N)f8' representation I explained above?
There isn't. You could make a subclass that tracks this, but you would have to implement it carefully to maintain the information.
There is an example of how to do that here:
http://www.scipy.org/Subclasses
Regards Stéfan _______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/764323a14e554c97ab74177e0bce51d4.jpg?s=120&d=mm&r=g)
Edson Tadeu wrote:
For now, I solved it using a view with a different type:
from numpy import * N = 5 a=zeros(N,'3f8') b=a.view() b.dtype='f8' b.shape = N,3
Note that this doesn't quite do what you want. I was wrong about the dtype='3f8' syntax: it just gives you a regular float array with the shape changed appropriately (at least in recent version of numpy; if you are getting something different, what version are you using?). In [24]: from numpy import * In [25]: N = 5 In [26]: zeros(N, dtype='3f8') Out[26]: array([[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) If you want a shape-(N,) record array, you need a different dtype: In [28]: zeros(N, dtype='f8,f8,f8') Out[28]: array([(0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)], dtype=[('f0', '<f8'), ('f1', '<f8'), ('f2', '<f8')]) In [31]: zeros(N, dtype=dtype([('x', float), ('y', float), ('z', float)])) Out[31]: array([(0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0), (0.0, 0.0, 0.0)], dtype=[('x', '<f8'), ('y', '<f8'), ('z', '<f8')]) To go back, you can give .view() an argument: In [30]: zeros(N, dtype='f8,f8,f8').view(dtype((float, 3))) Out[30]: array([[ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 0., 0.]]) -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
participants (4)
-
Alan G Isaac
-
Edson Tadeu
-
Robert Kern
-
Stefan van der Walt