2012-05-16 4 views
17

У меня есть огромный словарь что-то вроде этого:преобразование 2d словарь в Numpy матрицы

d[id1][id2] = value 

пример:

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

и так далее ..

Каждый из «AUTH «ключи могут иметь любой набор« жанров », связанных с ними. Значение для ключевого элемента - это количество книг, которые они написали.

Теперь я хочу, чтобы преобразовать его в виде матрицы ... что-то вроде:

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

Как мне это сделать? Благодаря

+0

первой итерация через словарь, а затем найти число строк и столбцов .. после этого, как я итерация преобразования каждой записи в виде определенного вектора .., а затем в другой итерации через id1 .. связывая его с их векторы – Fraz

+0

Вы просто хотите, чтобы это было напечатано так? Зачем нужно входить в матрицу numpy –

+0

@PaulSeeb: no no .. на самом деле я хочу позже выполнить svd этой матрицы .. – Fraz

ответ

9

Используйте список понимание, чтобы превратить Dict в список списков и/или Numpy массива:

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

EDIT

Видимо у вас нерегулярный количество ключей в каждом суб-словарь. Составьте список всех жанров:

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

А потом перебирать словарей обычным способом:

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) 

В основном я пытаюсь добавить значение из каждого ключа в genres к списку , Если ключ отсутствует, он выдает ошибку. Я поймаю ошибку и добавлю 0 к списку.

+0

Привет, это дает мне: array ([[20 , 30], [50]], dtype = object) , но я ожидал, что был [[20, 30, 0], [0,0,50]] – Fraz

+0

@Fraz: ах, поэтому у вас есть нерегулярное число ключей для каждого автора dict. Позвольте мне изменить. –

22

pandas делают это очень хорошо:

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) 

Выход:

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

именно то, что мне нужно - спасибо! –

+0

@HYRY Может ли pandas DataFrame использоваться для ввода matplotlib.pcolor для создания карты тепла? Или нужно сначала преобразовать в массив numpy? –

+0

В случае значений словаря переменной длины используйте 'DataFrame.from_dict (books, orient = 'index'). Fillna (0)' вместо этого для предотвращения 'ValueError'. – interpolack

0

В 2018 году, я думаю, что панды 0,22 поддерживает эту out of the box. В частности, пожалуйста, проверьте метод класса from_dictDataFrame.

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) 
Смежные вопросы