Efficient way to convert numpy record array to a list of dictionary
How do I convert the numpy record array below:
recs = [('Bill', 31, 260.0), ('Fred', 15, 145.0)]
r = rec.fromrecords(recs, names='name, age, weight', formats='S30, i2, f4')
to a list of dictionary like:
[{'name': 'Bill', 'age': 31, 'weight': 260.0},
'name': 'Fred',开发者_开发问答 'age': 15, 'weight': 145.0}]
I am not sure there is built-in function for that or not, but following could do the work.
>>> [dict(zip(r.dtype.names,x)) for x in r]
[{'age': 31, 'name': 'Bill', 'weight': 260.0},
{'age': 15, 'name': 'Fred', 'weight': 145.0}]
This depends on the final structure required. This example shows a numpy recarray composed of several 1D subsets. To have a python dictionary instead, a possible conversion is:
import numpy as np
a = np.rec.array([np.array([1,3,6]), np.array([3.4,4.2,-1.2])], names=['t', 'x'])
b = {name:a[name] for name in a.dtype.names}
Here's a solution that works in the following cases not covered by the other answers:
- 0-dimensional arrays (scalars). e.g.
np.array((1, 2), dtype=[('a', 'float32'), ('b', 'float32')])
- elements of type
np.void
(result of indexing a record array) - multi-dimensional arrays of structs
- structs containing structs, (e.g.
structured_to_dict(np.zeros((), dtype=[('a', [('b', 'float32', (2,))])]))
) - Combinations of any of the above.
def structured_to_dict(arr: np.ndarray):
import numpy as np
if np.ndim(arr) == 0:
if arr.dtype.names == None:
return arr.item()
# accessing by int does *not* work when arr is a zero-dimensional array!
return {k: structured_to_dict(arr[k]) for k in arr.dtype.names}
return [structured_to_dict(v) for v in arr]
Answered at Numpy-discussion by Robert Kern
Copy of concluding email from that discussion:
How do I convert the numpy record array below: recs = [('Bill', 31, 260.0), ('Fred', 15, 145.0)] r = rec.fromrecords(recs, names='name, age, weight', formats='S30, i2, f4') to a list of dictionary like: [{'name': 'Bill', 'age': 31, 'weight': 260.0}, 'name': 'Fred', 'age': 15, 'weight': 145.0}]
Assuming that your record array is only 1D:
In [6]: r.dtype.names Out[6]: ('name', 'age', 'weight')
In [7]: names = r.dtype.names
In [8]: [dict(zip(names, record)) for record in r] Out[8]: [{'age': 31, 'name': 'Bill', 'weight': 260.0}, {'age': 15, 'name': 'Fred', 'weight': 145.0}]
精彩评论