2012-05-16 28 views
17

tengo un enorme diccionario de algo como esto:convertir un diccionario 2d a una matriz numpy

d[id1][id2] = value 

ejemplo:

books["auth1"]["humor"] = 20 
books["auth1"]["action"] = 30 
books["auth2"]["comedy"] = 20 

y así sucesivamente ..

Cada uno de los "auth "las claves pueden tener cualquier conjunto de" géneros "asociados con ellos. El valor de un elemento con clave es la cantidad de libros que escribió.

Ahora lo que quiero es convertirlo en una forma de matriz ... algo así como:

    "humor"  "action"  "comedy" 
     "auth1"   20   30    0 
     "auth2"   0   0    20 

¿Cómo puedo hacer esto? Gracias

+0

primera iteración a través del diccionario y luego encontrar el número de filas y columnas .. después de que a medida que estoy iterando convertir cada entrada como un vector definido .. y luego en otra iteración a través de ID 1 .. asociarlo con su vectores – Fraz

+0

¿Desea que se imprima así? ¿Por qué necesita ir a una matriz numpy –

+0

@PaulSeeb: no no ... en realidad quiero más adelante para realizar svd de esta matriz ... – Fraz

Respuesta

9

Utilice una lista por comprensión a su vez un diccionario en una lista de listas y/o una matriz numpy:

np.array([[books[author][genre] for genre in sorted(books[author])] for author in sorted(books)]) 

EDITAR

Al parecer, usted tiene un número irregular de llaves en cada sub-diccionario. Haga una lista de todos los géneros:

genres = ['humor', 'action', 'comedy'] 

Y luego iterar sobre los diccionarios de la manera normal:

list_of_lists = [] 
for author_name, author in sorted(books.items()): 
    titles = [] 
    for genre in genres: 
     try: 
      titles.append(author[genre]) 
     except KeyError: 
      titles.append(0) 
    list_of_lists.append(titles) 

books_array = numpy.array(list_of_lists) 

Básicamente estoy tratando de añadir un valor de cada clave en genres a una lista . Si la clave no está allí, arroja un error. Capté el error y agregué un 0 a la lista.

+0

Hola, esto me da: matriz ([[20 , 30], [50]], dtype = object) pero lo que esperaba era [[20, 30, 0], [0,0,50]] – Fraz

+0

@Fraz: ah, entonces tiene un número irregular de llaves para cada dictor de autor. Déjame editar. –

22

pandas hacer esto muy bien:

books = {} 
books["auth1"] = {} 
books["auth2"] = {} 
books["auth1"]["humor"] = 20 
books["auth1"]["action"] = 30 
books["auth2"]["comedy"] = 20 

from pandas import * 

df = DataFrame(books).T.fillna(0) 

La salida es:

 action comedy humor 
auth1  30  0  20 
auth2  0  20  0 
+0

exactamente lo que necesitaba, ¡gracias! –

+0

@HYRY ¿Se puede utilizar un DataFrame pandas como entrada para matplotlib.pcolor para crear un mapa de calor? ¿O uno tiene que convertirse a una matriz numpy primero? –

+0

En caso de valores de diccionario de longitud variable, use 'DataFrame.from_dict (books, orient = 'index'). Fillna (0)' en su lugar para evitar 'ValueError'. – interpolack

0

En 2018, creo que las pandas 0,22 apoya esta out of the box. Específicamente, compruebe el método de clase from_dict de DataFrame.

books = {} 
books["auth1"] = {} 
books["auth2"] = {} 
books["auth1"]["humor"] = 20 
books["auth1"]["action"] = 30 
books["auth2"]["comedy"] = 20 

pd.DataFrame.from_dict(books, orient='columns', dtype=None) 
Cuestiones relacionadas