加载json数据
data = json.load(open('data/foods-2011-10-03.json'))
data
大概观察一下数据的结构,是由多个字典形式的数据组成
data[0].keys()
查看数据含有的字段名
然后将数据转换为DataFrame格式
df = pd.DataFrame(data)
df
现在我们可以比较清楚的看到数据的结构,主要的数据有食物品类、组成成分、id标识、生产厂商、营养物、份数、标签
这里面我们需要的数据主要是食物品类、组成成分、id标识、营养物
营养物这一列又是一个个字典组成,所以我们需要单独处理
从原始json数据值展开营养物数据,组成一个新的DataFrame,并给每一个数据添加对应的id标识。
nutrients = []
for rec in data:
nutrient = pd.DataFrame(rec['nutrients'])
nutrient['id'] = rec['id']
nutrients.append(nutrient)
nutrients
获得的nutrients是一个有多个DataFrame组成的列表,现在我们需要把他们拼成一个,因为每一个DataFrame的数据结构相同,所以直接使用concat函数进行拼接
nutrients = pd.concat(nutrients, ignore_index=True)
nutrients
然后我们在取出df表中食物品类、组成成分、id标识列,组成一个新的数据表info
# 组成info新表
info = df[['description', 'group', 'id']]
info
查看这两个数据的重复行个数
对nutrients的重复值进行删除
nutrients.drop_duplicates(inplace=True)
两个数据表存在相同的字段名,为了避免混淆,我这里使用新的字段名进行更改
先设置用于更改列名的映射值
mapping1 = {
'description':'nut_description',
'group':'nut_group'
}
mapping2 = {
'description':'food_description',
'group':'food_group'
}
根据映射值进行更改
nutrients = nutrients.rename(columns=mapping1)
food_info = food_info.rename(columns=mapping2)
根据id标识列,将两个数据表连接起来
food_nut_info = pd.merge(nutrients, food_info, on='id', how='outer')
food_nut_info
使用聚合函数groupby得到每一种营养物质在每种食品中含量的中位数
result = food_nut_info.groupby(by=['nut_description', 'food_group'])['value'].quantile(0.5)
result
然后我们取出含有蛋白质的物质,并且进行可视化处理,观察哪种食物蛋白质含量最高
# 对蛋白质含量进行升序的排序
results = result['Protein'].sort_values()
# 根据数据画出一个蛋白质含量条形图
plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False
plt.subplots(figsize=(12, 8))
plt.subplot(111, facecolor='black')
plt.barh(y=results.index, width=results.values, color='orange')
plt.title('各食品蛋白质含量')
plt.xlabel('含量/g')
plt.ylabel('食品类型')
plt.show()
后续学习完数据分析继续更新
未完待更新。。。