# [Numpy-discussion] dtype "reduction" [SOLVED]

Nicolas Rougier Nicolas.Rougier@inria...
Tue Jan 15 11:37:52 CST 2013

```
I ended coding the dtype reduction, it's not foolproof but it might be useful for others as well.

Nicolas

import numpy as np

def dtype_reduce(dtype, level=0, depth=0):
"""
Try to reduce dtype up to a given level when it is possible

dtype =  [ ('vertex',  [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]),
('normal',  [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]),
('color',   [('r', 'f4'), ('g', 'f4'), ('b', 'f4'), ('a', 'f4')])]

level 0: ['color,vertex,normal,', 10, 'float32']
level 1: [['color', 4, 'float32']
['normal', 3, 'float32']
['vertex', 3, 'float32']]
"""
dtype = np.dtype(dtype)
fields = dtype.fields

# No fields
if fields is None:
if dtype.shape:
count = reduce(mul, dtype.shape)
else:
count = 1
size = dtype.itemsize/count
if dtype.subdtype:
name = str( dtype.subdtype[0] )
else:
name = str( dtype )
return ['', count, name]
else:
items = []
name = ''
# Get reduced fields
for key,value in fields.items():
l =  dtype_reduce(value[0], level, depth+1)
if type(l[0]) is str:
items.append( [key, l[1], l[2]] )
else:
items.append( l )
name += key+','

# Check if we can reduce item list
ctype = None
count = 0
for i,item in enumerate(items):
# One item is a list, we cannot reduce
if type(item[0]) is not str:
return items
else:
if i==0:
ctype = item[2]
count += item[1]
else:
if item[2] != ctype:
return items
count += item[1]
if depth >= level:
return [name, count, ctype]
else:
return items

if __name__ == '__main__':

# Fully reductible
dtype =  [ ('vertex',  [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]),
('normal',  [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]),
('color',   [('r', 'f4'), ('g', 'f4'), ('b', 'f4'), ('a', 'f4')])]
print 'level 0:'
print dtype_reduce(dtype,level=0)
print 'level 1:'
print dtype_reduce(dtype,level=1)
print

# Not fully reductible
dtype =  [ ('vertex',  [('x', 'i4'), ('y', 'i4'), ('z', 'i4')]),
('normal',  [('x', 'f4'), ('y', 'f4'), ('z', 'f4')]),
('color',   [('r', 'f4'), ('g', 'f4'), ('b', 'f4'), ('a', 'f4')])]
print 'level 0:'
print dtype_reduce(dtype,level=0)
print

# Not reductible at all
dtype =  [ ('vertex',  [('x', 'f4'), ('y', 'f4'), ('z', 'i4')]),
('normal',  [('x', 'f4'), ('y', 'f4'), ('z', 'i4')]),
('color',   [('r', 'f4'), ('g', 'f4'), ('b', 'i4'), ('a', 'f4')])]
print 'level 0:'
print dtype_reduce(dtype,level=0)

On Dec 27, 2012, at 9:11 , Nicolas Rougier wrote:

>
> Yep, I'm trying to construct dtype2 programmaticaly and was hoping for some function giving me a "canonical" expression of the dtype. I've started playing with fields but it's just a bit harder than I though (lot of different cases and recursion).
>
> Thanks for the answer.
>
>
> Nicolas
>
> On Dec 27, 2012, at 1:32 , Nathaniel Smith wrote:
>
>> On Wed, Dec 26, 2012 at 8:09 PM, Nicolas Rougier
>> <Nicolas.Rougier@inria.fr> wrote:
>>>
>>>
>>> Hi all,
>>>
>>>
>>> I'm looking for a way to "reduce" dtype1 into dtype2 (when it is possible of course).
>>> Is there some easy way to do that by any chance ?
>>>
>>>
>>> dtype1 = np.dtype( [ ('vertex',  [('x', 'f4'),
>>>                                 ('y', 'f4'),
>>>                                 ('z', 'f4')]),
>>>                   ('normal',  [('x', 'f4'),
>>>                                ('y', 'f4'),
>>>                                ('z', 'f4')]),
>>>                   ('color',   [('r', 'f4'),
>>>                                ('g', 'f4'),
>>>                                ('b', 'f4'),
>>>                                ('a', 'f4')]) ] )
>>>
>>> dtype2 = np.dtype( [ ('vertex',  'f4', 3),
>>>                    ('normal',  'f4', 3),
>>>                    ('color',   'f4', 4)] )
>>>
>>
>> If you have an array whose dtype is dtype1, and you want to convert it
>> into an array with dtype2, then you just do
>> my_dtype2_array = my_dtype1_array.view(dtype2)
>>
>> If you have dtype1 and you want to programmaticaly construct dtype2,
>> then that's a little more fiddly and depends on what exactly you're
>> trying to do, but start by poking around with dtype1.names and
>> dtype1.fields, which contain information on how dtype1 is put together
>> in the form of regular python structures.
>>
>> -n
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion@scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion

```

More information about the NumPy-Discussion mailing list