2014-07-16 30 views
6

Powiedz, że mam dane takie jak d = [dict(animal='cat', weight=5), dict(animal='dog', weight=20)] (w zasadzie JSON, gdzie wszystkie wpisy mają spójne typy danych).Najłatwiejszy sposób utworzenia tablicy rekordów NumPy z listy słowników?

W Pandach możesz zrobić to z tabelą z df = pandas.DataFrame(d) - czy jest coś porównywalnego z prostymi tablicami NumPy? np.rec.fromrecords(d) wydaje się nie dała mi tego, czego chcę.

+1

Jakie struktury danych chcesz skończyć z? Tylko szereg obiektów? – agconti

+0

A NumPy [tablica rekordów] (http://docs.scipy.org/doc/numpy/reference/generated/numpy.recarray.html), więc mogę zrobić coś w stylu 'pets ['weight']' (co być "[5, 20]" w tym przypadku). – Roger

Odpowiedz

0

Można użyć 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) 
+0

Niestety, to po prostu słownik w ndarray, z którym naprawdę nie można wiele zrobić. – Roger

2

Cóż można uczynić swoje życie dodatkowo łatwy i po prostu polegać na Pand od numpy nie korzysta z nagłówków kolumn

pandy

df = pandas.DataFrame(d) 
numpyMatrix = df.as_matrix() #spits out a numpy matrix 

Możesz też zignorować Pandy i użyć funkcji numpy + ze zrozumieniem listy, aby powalić dyktowane wartości i zapisać je jako macierz

Numpy

numpMatrix = numpy.matrix([each.values() for each in d]) 
+1

Miałem nadzieję uniknąć stosowania pand, a drugi przykład nie zachowuje nazw pól ("animal" i "weight"). – Roger

4

Można zrobić pusty uporządkowaną tablicę odpowiedniej wielkości i dtype, a następnie wypełnić go z listy.

http://docs.scipy.org/doc/numpy/user/basics.rec.html

tablice strukturalne mogą być wypełnione przez pole lub wiersz po wierszu. ... Jeśli wypełnić go wiersz po wierszu, to zajmuje się krotki (ale nie listę lub tablicę!):

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')] 

pola w dt występują w takiej samej kolejności jak w 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')]) 

Przy odrobinie więcej testów odkryłem, że mogę utworzyć macierz bezpośrednio z values.

In [83]: a = np.array(values, dtype=dt) 

In [84]: a 
Out[84]: 
array([(5, 'cat'), (20, 'dog')], 
     dtype=[('weight', '<i4'), ('animal', 'S10')]) 

The dtype można było wywnioskować z jednego (lub więcej) słownika przedmiotów:

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

produkcji:

dtype=[('weight', '<i4'), ('animal', 'S13')] 
+0

To powinno zadziałać, ale liczyłem na coś wygodniejszego, co pozwoli określić typy danych. Chyba nie ma nic wbudowanego. – Roger

+1

'loadtxt' i' genfromtxt' dedukują typy danych z plików 'csv'. Więc możesz zapisać swoje wartości do pliku tekstowego, a następnie załadować go.Nie, żebym to polecił. – hpaulj