2015-10-15 2 views
10

У меня есть словарь словарей вида:создать панда dataframe из словаря словарей

{'user':{movie:rating} } 

Например,

{Jill': {'Avenger: Age of Ultron': 7.0, 
          'Django Unchained': 6.5, 
          'Gone Girl': 9.0, 
          'Kill the Messenger': 8.0} 
'Toby': {'Avenger: Age of Ultron': 8.5, 
           'Django Unchained': 9.0, 
           'Zoolander': 2.0}} 

Я хочу, чтобы преобразовать эту Dict из dicts в панде dataframe с столбец 1 имя пользователя и другие столбцы рейтинги фильмов, т.е.

user Gone_Girl Horrible_Bosses_2 Django_Unchained Zoolander etc. \ 

Howev er, некоторые пользователи не оценивали фильмы и поэтому эти фильмы не включены в значения() для этого пользовательского ключа(). Было бы неплохо в этих случаях просто заполнить запись NaN.

В настоящее время, я перебирать ключи, заполнить список, а затем использовать этот список для создания dataframe:

data=[] 
for i,key in enumerate(movie_user_preferences.keys()): 
    try:    
     data.append((key 
        ,movie_user_preferences[key]['Gone Girl'] 
        ,movie_user_preferences[key]['Horrible Bosses 2'] 
        ,movie_user_preferences[key]['Django Unchained'] 
        ,movie_user_preferences[key]['Zoolander'] 
        ,movie_user_preferences[key]['Avenger: Age of Ultron'] 
        ,movie_user_preferences[key]['Kill the Messenger'])) 
    # if no entry, skip 
    except: 
     pass 
df=pd.DataFrame(data=data,columns=['user','Gone_Girl','Horrible_Bosses_2','Django_Unchained','Zoolander','Avenger_Age_of_Ultron','Kill_the_Messenger']) 

Но это только дает мне dataframe пользователей, которые оценили все фильмы в набор.

Моя цель состоит в том, чтобы добавить к списку данных, итерации над метками фильма (вместо приведенного выше подхода к грубой силе) и, во-вторых, создать фрейм данных, который включает всех пользователей, и который устанавливает нулевые значения в элементах, которые делают не имеют рейтингов фильмов.

ответ

17

Вы можете передать Dict в Словаре конструктору DataFrame:

In [11]: d = {'Jill': {'Django Unchained': 6.5, 'Gone Girl': 9.0, 'Kill the Messenger': 8.0, 'Avenger: Age of Ultron': 7.0}, 'Toby': {'Django Unchained': 9.0, 'Zoolander': 2.0, 'Avenger: Age of Ultron': 8.5}} 

In [12]: pd.DataFrame(d) 
Out[12]: 
         Jill Toby 
Avenger: Age of Ultron 7.0 8.5 
Django Unchained   6.5 9.0 
Gone Girl    9.0 NaN 
Kill the Messenger  8.0 NaN 
Zoolander    NaN 2.0 

Или использовать from_dict метод:

In [13]: pd.DataFrame.from_dict(d) 
Out[13]: 
         Jill Toby 
Avenger: Age of Ultron 7.0 8.5 
Django Unchained   6.5 9.0 
Gone Girl    9.0 NaN 
Kill the Messenger  8.0 NaN 
Zoolander    NaN 2.0 

In [14]: pd.DataFrame.from_dict(d, orient='index') 
Out[14]: 
     Django Unchained Gone Girl Kill the Messenger Avenger: Age of Ultron Zoolander 
Jill    6.5   9     8      7.0  NaN 
Toby    9.0  NaN     NaN      8.5   2 
+0

Есть ли способ сделать имена пользователей отдельными столбцами вместо индекса? – Feynman27

+3

pd.DataFrame.from_dict (d, orient = 'index'). Reset_index() –

+0

Отлично. Спасибо! – Feynman27

0

Это перебор подход представляется также работать, но итерация над На мой взгляд, лейблы фильмов по-прежнему будут более надежными.

data=[] 
for i,key in enumerate(movie_user_preferences.keys()): 
    try:    
     data.append((key 
        ,movie_user_preferences[key]['Gone Girl'] if 'Gone Girl' in movie_user_preferences[key] else 'NaN' 
        ,movie_user_preferences[key]['Horrible Bosses 2'] if 'Horrible Bosses 2' in movie_user_preferences[key] else 'NaN' 
        ,movie_user_preferences[key]['Django Unchained'] if 'Django Unchained' in movie_user_preferences[key] else 'NaN' 
        ,movie_user_preferences[key]['Zoolander'] if 'Zoolander' in movie_user_preferences[key] else 'NaN' 
        ,movie_user_preferences[key]['Avenger: Age of Ultron'] if 'Avenger: Age of Ultron' in movie_user_preferences[key] else 'NaN' 
        ,movie_user_preferences[key]['Kill the Messenger'] if 'Kill the Messenger' in movie_user_preferences[key] else 'NaN')) 

    # if no entry, skip 
    except: 
     pass 


user Gone_Girl Horrible_Bosses_2 Django_Unchained Zoolander \ 
0  Sam   6     3    7.5   7 
1  Max  10     6    7.0  10 
2 Robert  NaN     5    7.0   9 
3  Toby  NaN    NaN    9.0   2 
4 Julia  6.5    NaN    6.0  6.5 
5 William   7     4    8.0   4 
6  Jill   9    NaN    6.5  NaN 

Avenger_Age_of_Ultron Kill_the_Messenger 
0     10.0    5.5 
1     7.0     5 
2     8.0     9 
3     8.5    NaN 
4     10.0     6 
5     6.0    6.5 
6     7.0     8 
Смежные вопросы