开发者

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}]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜