2012-05-16 20 views
17

Mam ogromny słownika coś takiego:konwersji 2D do słownika numpy matrycy

d[id1][id2] = value 

przykład:

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

i tak dalej ..

Każdy z „auth "klucze mogą mieć dowolny zestaw" gatunków "powiązanych z nimi. Wartość kluczowanego przedmiotu to liczba książek, które napisali.

Teraz to, co chcę, aby przekształcić go w postaci macierzy ... coś jak:

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

Jak to zrobić? Dzięki

+0

pierwszej iteracji thru słowniku, a następnie znalezienie liczby wierszy i kolumn .. Po tym jak ja iteracji konwersji każdego wpisu jako zdefiniowany wektor .. a następnie w innym iteracji thru ID1 .. skojarzenie go z ich wektory – Fraz

+0

Po prostu chcesz wydrukować w ten sposób? Dlaczego musi wejść w matrycę numpy? –

+0

@PaulSeeb: nie, nie, faktycznie chcę później wykonać svd tej macierzy .. – Fraz

Odpowiedz

9

Użyj listowych, aby włączyć dict do listy list i/lub numpy tablicy:

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

EDIT

Widocznie masz nieregularną liczbę klawiszy w każdym sub-słownik. Zrób listę wszystkich gatunkach:

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

A następnie iteracyjne nad słownikami w normalny sposób:

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) 

Zasadniczo jestem próbując dołączyć wartość od każdego klawisza w genres do listy . Jeśli klucza tam nie ma, zgłasza błąd. Zgłaszam błąd i zamiast tego dołączam 0 do listy.

+0

Cześć, to daje mi: array ([[20 , 30], [50]], dtype = obiekt) ale oczekiwałem, że [[20, 30, 0], [0,0,50]] – Fraz

+0

@Fraz: ah, więc masz nieregularny numer kluczy dla każdego autora dykt. Pozwól mi edytować. –

22

pandas to zrobić bardzo dobrze:

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) 

Wyjście jest:

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

dokładnie to, czego potrzebowałem - dziękuję! –

+0

@HYRY Czy pandas DataFrame może być użyty jako dane wejściowe dla matplotlib.pcolor do utworzenia mapy ciepła? Czy najpierw trzeba przekonwertować na tablicę numpy? –

+0

W przypadku wartości słownika o zmiennej długości, użyj 'DataFrame.from_dict (books, orient = 'index'). Fillna (0)' zamiast tego, aby zapobiec 'ValueError'. – interpolack

0

W 2018 roku, myślę, że Pandy 0.22 obsługuje tę out of the box. W szczególności sprawdź metodę klasy from_dict pod numerem 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)