假设我有d = [dict(animal='cat', weight=5), dict(animal='dog', weight=20)]
之类的数据(基本上是JSON,其中所有条目都有一致的数据类型)。
在Pandas中你可以用df = pandas.DataFrame(d)
创建一个表 - 是否有类似于普通NumPy记录数组的东西? np.rec.fromrecords(d)
似乎没有给我我想要的东西。
答案 0 :(得分:5)
你可以创建一个正确大小和dtype的空结构化数组,然后从列表中填充它。
http://docs.scipy.org/doc/numpy/user/basics.rec.html
结构化数组可以按字段或逐行填充。 ... 如果你逐行填充它,它需要一个元组(但不是列表或数组!):
In [72]: dt=dtype([('weight',int),('animal','S10')])
In [73]: values = [tuple(each.values()) for each in d]
In [74]: values
Out[74]: [(5, 'cat'), (20, 'dog')]
dt
中的字段与values
中的字段顺序相同。
In [75]: a=np.zeros((2,),dtype=dt)
In [76]: a[:]=[tuple(each.values()) for each in d]
In [77]: a
Out[77]:
array([(5, 'cat'), (20, 'dog')],
dtype=[('weight', '<i4'), ('animal', 'S10')])
通过更多测试,我发现我可以直接从values
创建数组。
In [83]: a = np.array(values, dtype=dt)
In [84]: a
Out[84]:
array([(5, 'cat'), (20, 'dog')],
dtype=[('weight', '<i4'), ('animal', 'S10')])
dtype
可以从一个(或多个)字典项中推断出来:
def gettype(v):
if isinstance(v,int): return 'int'
elif isinstance(v,float): return 'float'
else:
assert isinstance(v,str)
return '|S%s'%(len(v)+10)
d0 = d[0]
names = d0.keys()
formats = [gettype(v) for v in d0.values()]
dt = np.dtype({'names':names, 'formats':formats})
制造
dtype=[('weight', '<i4'), ('animal', 'S13')]
答案 1 :(得分:4)
好吧,你可以让你的生活更轻松,只需依靠熊猫,因为numpy不使用列标题
<强>熊猫强>
df = pandas.DataFrame(d)
numpyMatrix = df.as_matrix() #spits out a numpy matrix
或者您可以忽略Pandas并使用numpy + list comprehension将dicts击倒为值并存储为矩阵
<强> numpy的强>
numpMatrix = numpy.matrix([each.values() for each in d])
答案 2 :(得分:1)
我的建议(通常略微改进hpaulj's answer):
dicts = [dict(animal='cat', weight=5), dict(animal='dog', weight=20)]
创建od dtype
对象:
dt_tuples = []
for key, value in dicts[0].items():
if not isinstance(value, str):
value_dtype = np.array([value]).dtype
else:
value_dtype = '|S{}'.format(max([len(d[key]) for d in dicts]))
dt_tuples.append((key, value_dtype))
dt = np.dtype(dt_tuples)
如您所见,字符串处理存在问题-我们需要检查它的最大长度以定义dtype。如果您的字典中没有字符串值,或者您确定所有这些值的长度都完全相同,则可以跳过此附加条件。
如果您要寻找单线飞机,将是这样的:
dt = np.dtype([(k, np.array([v]).dtype if not isinstance(v, str) else '|S{}'.format(max([len(d[k]) for d in dicts]))) for k, v in dicts[0].items()])
(出于可读性考虑,最好将其破坏)。
值列表:
values = [tuple(d[name] for name in dt.names) for d in dicts]
因为我们遍历dt.names
,所以我们确定值的顺序是正确的。
最后,创建数组:
a = np.array(values, dtype=dt)
答案 3 :(得分:-1)
您可以使用np.asaray()
:
In [1]: import numpy as np
In [2]: d =np.asarray( [dict(animal='cat', weight=5), dict(animal='dog', weight=20)])
In [3]: d
Out[3]: array([{'weight': 5, 'animal': 'cat'}, {'weight': 20, 'animal': 'dog'}], dtype=object)