2

Given a list of dictionaries as follows:

dict_data = [
    {'name': 'r1', 'interval': [1800.0, 1900.0], 'bool_condition': [True, False]},
    {'name': 'r2', 'interval': [1600.0, 1500.0], 'bool_condition': [False]},
    {'name': 'r3', 'interval': [1400.0, 1600.0], 'bool_condition': [True]}
]

I would like to create a record array from the dictionaries data. But when I try the following I get ValueError

import numpy as np
dt = np.dtype([
('name', np.str_, 50), ('interval', np.float64, (2,)),
    ('bool_condition', np.bool)
])
values = [tuple(val.values()) for val in dict_data]
arr = np.rec.array(values, dtype=dt)

Error: ValueError: cannot set an array element with a sequence

I would like to know how could I have a more correct dtype and then create the record array from the list of dictionaries.

saloua
  • 2,433
  • 4
  • 27
  • 37

2 Answers2

4

It's very convenient to do that with pandas :

 In [247]: pd.DataFrame(dict_data)[['name','interval','bool_condition']].to_records(False)

Out[247]: 
rec.array([('r1', [1800.0, 1900.0], [True, False]),
 ('r2', [1600.0, 1500.0], [False]), ('r3', [1400.0, 1600.0], [True])], 
          dtype=[('name', 'O'), ('interval', 'O'), ('bool_condition', 'O')])

['name','interval','bool_condition'] ensure the order of the fields.

B. M.
  • 18,243
  • 2
  • 35
  • 54
3

One problem is that the iteration of a dictionary does not preserve the order. You can see this by looking at print values[0] which gives ([1800.0, 1900.0], [True, False], 'r1') if I use your code.

Rather use

import numpy as np
dt = np.dtype([
    ('name', np.str_, 50),
    ('interval', np.float64, (2,)),
    ('bool_condition', np.bool)
])
values = [
    tuple([val['name'], val['interval'], val['bool_condition']])
    for val in dict_data
]
arr = np.rec.array(values, dtype=dt)

Another thing is that the bool_condition in your data is a list and not just a boolean. So you might want to change your dtype to:

dt = np.dtype([
    ('name', np.str_, 50),
    ('interval', np.float64, (2,)),
    ('bool_condition', list)
])
Eric
  • 95,302
  • 53
  • 242
  • 374
Fabian Rost
  • 2,284
  • 2
  • 15
  • 27