Python 从列中分解dict

Python 从列中分解dict,python,pandas,Python,Pandas,我有以下建议: movie_id rating_all 0 tt7653254 [{'age': 'all', 'avg_rating': 8.1, 'count': 109326}, {'age': '<18', 'avg_rating': 8.8, 'count': 318}, {'age': '18-29', 'avg_rating': 8.3, 'count': 29740}, {'age': '30-44', 'avg_rating': 8.0, 'cou

我有以下建议:

    movie_id    rating_all 
0   tt7653254   [{'age': 'all', 'avg_rating': 8.1, 'count': 109326}, {'age': '<18', 'avg_rating': 8.8, 'count': 318}, {'age': '18-29', 'avg_rating': 8.3, 'count': 29740}, {'age': '30-44', 'avg_rating': 8.0, 'count': 33012}, {'age': '45+', 'avg_rating': 7.7, 'count': 7875}]
1   tt8579674   [{'age': 'all', 'avg_rating': 8.6, 'count': 9420}, {'age': '<18', 'avg_rating': 9.1, 'count': 35}, {'age': '18-29', 'avg_rating': 8.7, 'count': 2437}, {'age': '30-44', 'avg_rating': 8.5, 'count': 2529}, {'age': '45+', 'avg_rating': 8.3, 'count': 960}]
2   tt7286456   [{'age': 'all', 'avg_rating': 8.6, 'count': 592441}, {'age': '<18', 'avg_rating': 9.1, 'count': 2244}, {'age': '18-29', 'avg_rating': 8.7, 'count': 160506}, {'age': '30-44', 'avg_rating': 8.5, 'count': 160158}, {'age': '45+', 'avg_rating': 8.3, 'count': 30451}]
3   tt1302006   [{'age': 'all', 'avg_rating': 8.1, 'count': 187675}, {'age': '<18', 'avg_rating': 8.7, 'count': 461}, {'age': '18-29', 'avg_rating': 8.3, 'count': 41951}, {'age': '30-44', 'avg_rating': 7.9, 'count': 59729}, {'age': '45+', 'avg_rating': 7.8, 'count': 18550}]
4   tt7131622   [{'age': 'all', 'avg_rating': 7.8, 'count': 323152}, {'age': '<18', 'avg_rating': 8.4, 'count': 955}, {'age': '18-29', 'avg_rating': 7.9, 'count': 82133}, {'age': '30-44', 'avg_rating': 7.6, 'count': 95878}, {'age': '45+', 'avg_rating': 7.5, 'count': 26383}]
5   tt8637428   [{'age': 'all', 'avg_rating': 7.7, 'count': 21362}, {'age': '<18', 'avg_rating': 8.0, 'count': 45}, {'age': '18-29', 'avg_rating': 7.9, 'count': 5901}, {'age': '30-44', 'avg_rating': 7.6, 'count': 6492}, {'age': '45+', 'avg_rating': 7.3, 'count': 2133}]
和使用

json_normalize(data, 
               record_path=['rating_all'], 
               meta=['movie_id']).set_index('movie_id')

但没有人给出类似的东西。有没有一种简单的方法可以将字典分解成列?

假设我正确地解释了您要做的事情,您可以按如下方式实现:

从(我假设!!)开始是您的输入数据集:

    movie_id                                            ratings
0  tt7653254  [{'age': 'all', 'avg_rating': 8.1, 'count': 10...
1  tt8579674  [{'age': 'all', 'avg_rating': 8.6, 'count': 94...
2  tt7286456  [{'age': 'all', 'avg_rating': 8.6, 'count': 59...
3  tt1302006  [{'age': 'all', 'avg_rating': 8.1, 'count': 18...
4  tt7131622  [{'age': 'all', 'avg_rating': 7.8, 'count': 32...
5  tt8637428  [{'age': 'all', 'avg_rating': 7.7, 'count': 21...
其中评级值是实际列表,而不是字符串(如果它们是字符串,
x['ratings']=x.ratings.apply(eval)
,将它们转换为对象)

首先,要将列表中的每一行分解为一组行:

parsed = x.groupby('movie_id').ratings.apply(lambda x: pd.DataFrame(x.values[0])).reset_index()
这将给你:

> parsed.head(10)
    movie_id  level_1    age  avg_rating   count
0  tt1302006        0    all         8.1  187675
1  tt1302006        1    <18         8.7     461
2  tt1302006        2  18-29         8.3   41951
3  tt1302006        3  30-44         7.9   59729
4  tt1302006        4    45+         7.8   18550
5  tt7131622        0    all         7.8  323152
6  tt7131622        1    <18         8.4     955
7  tt7131622        2  18-29         7.9   82133
8  tt7131622        3  30-44         7.6   95878
9  tt7131622        4    45+         7.5   26383
...
我在这里使用的意思是,假设每部电影和年龄组只有一行数据,sum也会起作用

> tabulated
          avg_rating                        count                             
age            18-29 30-44  45+  <18  all   18-29   30-44    45+   <18         all
movie_id                                                                      
tt1302006        8.3   7.9  7.8  8.7  8.1   41951   59729  18550   461      187675
tt7131622        7.9   7.6  7.5  8.4  7.8   82133   95878  26383   955      323152
tt7286456        8.7   8.5  8.3  9.1  8.6  160506  160158  30451  2244      592441
tt7653254        8.3   8.0  7.7  8.8  8.1   29740   33012   7875   318      109326
tt8579674        8.7   8.5  8.3  9.1  8.6    2437    2529    960    35        9420
tt8637428        7.9   7.6  7.3  8.0  7.7    5901    6492   2133    45       21362
>制表
平均额定值计数

年龄18-29 30-44 45岁以上您的输入数据是如何格式化的还不是100%清楚。你的问题表明它将是一个系列,每一行都是一个列表?如果是这种情况,第一个代码段中的列标题表示什么?输入数据框是两列还是五列?
> parsed.head(10)
    movie_id  level_1    age  avg_rating   count
0  tt1302006        0    all         8.1  187675
1  tt1302006        1    <18         8.7     461
2  tt1302006        2  18-29         8.3   41951
3  tt1302006        3  30-44         7.9   59729
4  tt1302006        4    45+         7.8   18550
5  tt7131622        0    all         7.8  323152
6  tt7131622        1    <18         8.4     955
7  tt7131622        2  18-29         7.9   82133
8  tt7131622        3  30-44         7.6   95878
9  tt7131622        4    45+         7.5   26383
...
tabulated= parsed.pivot_table(
    index='movie_id',
    columns=['age'],
    values=['avg_rating','count'],
    aggfunc='mean'
)
> tabulated
          avg_rating                        count                             
age            18-29 30-44  45+  <18  all   18-29   30-44    45+   <18         all
movie_id                                                                      
tt1302006        8.3   7.9  7.8  8.7  8.1   41951   59729  18550   461      187675
tt7131622        7.9   7.6  7.5  8.4  7.8   82133   95878  26383   955      323152
tt7286456        8.7   8.5  8.3  9.1  8.6  160506  160158  30451  2244      592441
tt7653254        8.3   8.0  7.7  8.8  8.1   29740   33012   7875   318      109326
tt8579674        8.7   8.5  8.3  9.1  8.6    2437    2529    960    35        9420
tt8637428        7.9   7.6  7.3  8.0  7.7    5901    6492   2133    45       21362