数据分析:麦当劳食品营养数据探索并可视化

news2025/1/9 0:31:13

在这里插入图片描述

系列文章目录

作者:i阿极

作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页

😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍

📜📜📜如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!💪


专栏案例:数据分析
数据分析:某电商优惠卷数据分析
数据分析:旅游景点销售门票和消费情况分析
数据分析:消费者数据分析
数据分析:餐厅订单数据分析
数据分析:基于随机森林(RFC)对酒店预订分析预测
数据分析:基于K-近邻(KNN)对Pima人糖尿病预测分析

文章目录

  • 系列文章目录
  • 1、实验简介
  • 2、数据说明
    • 2.1数据集的整体特征
    • 2.2属性描述
  • 3、实验环境
  • 4、实验步骤
    • 4.1数据准备
    • 4.2数据质量检查
    • 4.3探索性分析
    • 4.4通过轮廓图和相关图来比较特征


1、实验简介

麦当劳(McDonald’s)是源自美国南加州的跨国连锁快餐店,也是全球最大的快餐连锁店,主要贩售汉堡包及薯条、炸鸡、汽水、冰品、沙拉、水果、咖啡等快餐食品。近年来,越来越多的人意识到快餐食品的不健康性,麦当劳也成了“垃圾食品”的代名词。美国纪录片《Super Size Me》记录了一个人一个月内只吃麦当劳后的身体变化,更引起了人们对于快餐食品营养超标的担忧。本分析旨在通过实证方法评估麦当劳数据集中260个产品的营养成分,我们先从一些标准的数据探索分析开始,之后讨论并使用Plotly绘制交互式散点图以展示不同的营养指标。

2、数据说明

2.1数据集的整体特征

|数据集名称 |数据类型 |特征数 |实例数 |值缺失 |相关任务|

数据集名称数据类型特征数实例数值缺失相关任务
麦当劳餐品营养成分数据集字符、数值数据242600可视化

2.2属性描述

属性数据类型字段描述
CategoryString食物类别
ItemString食品名称
Serving SizeString食用分量
CaloriesInteger卡路里
Calories from FatInteger来自脂肪的卡路里
Total FatInteger脂肪总量
Total Fat (% Daily Value)Integer脂肪总量占每日推荐摄入量的百分比
Saturated FatInteger饱和脂肪
Saturated Fat (% Daily Value)Integer饱和脂肪占每日推荐摄入量的百分比
Trans FatInteger反式脂肪
CholesterolInteger胆固醇
Cholesterol (% Daily Value)Integer胆固醇占每日推荐摄入量的百分比
SodiumInteger
Sodium (% Daily Value)Integer钠占每日推荐摄入量的百分比
CarbohydratesInteger碳水化合物
Carbohydrates (% Daily Value)Integer碳水化合物占每日推荐摄入量的百分比
Dietary FiberInteger膳食纤维
Dietary Fiber (% Daily Value)Integer膳食纤维占每日推荐摄入量的百分比
SugarsInteger糖分
ProteinInteger蛋白质
Vitamin A (% Daily Value)Integer维他命A占每日推荐摄入量的百分比
Vitamin C (% Daily Value)Integer维他命C占每日推荐摄入量的百分比
Calcium (% Daily Value)Integer钙占每日推荐摄入量的百分比
Iron (% Daily Value)Integer铁占每日推荐摄入量的百分比

3、实验环境

Python 3.9

Anaconda

Jupyter Notebook

4、实验步骤

4.1数据准备

加载需要的模块

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
import plotly.offline as py
py.init_notebook_mode(connected=True)
import plotly.graph_objs as go
import plotly.tools as tls
import warnings
warnings.filterwarnings('ignore')

加载数据


#加载数据集
menu = pd.read_csv("/home/mw/mcdonald_s_menu.csv")

#预览数据集前5行
menu.head()

在这里插入图片描述

查看数据集行列数

print("该数据集共有 {} 行 {} 列".format(menu.shape[0],menu.shape[1])) 

在这里插入图片描述

每一行代表一样麦当劳产品;24列,包括了产品的类别,名称,大小,以及营养成分(如卡路里,脂肪,胆固醇,钠,碳水化合物,膳食纤维,糖,蛋白质,维他命A,维他命C,钙,铁)等内容。

4.2数据质量检查

检查空值

menu.isnull().any()

在这里插入图片描述

各个column内容的描述性统计

menu.describe()

在这里插入图片描述

4.3探索性分析

首先,我们看一下每一类食品的数量,并绘图展示:

count_by_category = menu[["Category"]].groupby(["Category"]).size().reset_index(name = 'Counts').sort_values(by = "Counts", ascending = False)
count_by_category

在这里插入图片描述

#条形图
fig, ax = plt.subplots(figsize = (12,9))
ax = sns.barplot(x="Category", y="Counts", data = count_by_category).set_title("每一类食品的数量")

在这里插入图片描述

#饼形图
plt.figure(figsize = (12,9))
plt.pie(x = count_by_category["Counts"], labels=count_by_category["Category"], autopct='%1.0f%%',)
plt.show()

在这里插入图片描述

从条形图和饼形图可以看出,数量排名第一的品类是咖啡和茶,高达37%;之后是早餐(16%),冰沙奶昔(11%),饮品(10%),鸡肉鱼肉(10%)和牛肉猪肉(6%)。小吃,甜点和沙拉占比最少,其中沙拉类食品仅占所有食品的2%。

接下来,我们看看,不同品类的食物,其卡路里含量如何

#盒形图
fig, ax = plt.subplots(figsize = (12,9))
ax = sns.boxplot(x = 'Category', y = 'Calories', data = menu).set_title("卡路里")

在这里插入图片描述

一些有趣的发现:

  • 早餐系列、猪肉牛肉系列、鸡肉鱼肉系列的卡路里含量较高(主食),冰沙奶昔系列的卡路里含量最高;
  • 沙拉、小食、甜品、咖啡和茶的卡路里含量较低,饮品的卡路里含量最低;
  • 早餐系列、鸡肉鱼肉系列和咖啡茶系列有一些异常值(outlier),可能是一些大份食物。

以上分析提醒了我们,食品的卡路里含量(及其他成分含量)会受到其份量的影响,将食品调整至同样的份量可以让之后的分析更加客观。

通过回顾数据集中“Serving Size”一栏,我们发现麦当劳对份量的标注并不完全统一,有如下几种形式:

1)4.8 oz (136 g) 2)1 cookie (33 g) 3)21 fl oz cup 4) 1 carton (236 ml) 5) 6 fl oz (177 ml) 6) 16.9 fl oz

固体食物的份量标注比较统一,都是按1)的形式,标出了oz和g两种重量单位,唯一的特例是2),只标注了g这一重量单位。

半液态和液态食物的份量标注比较杂乱,有些和固体食物一样标注了重量,但大部分属于3)-6),即标注fl oz和/或ml两种体积单位。

因此我们的提取原则是,重量单位优先提取g,没有g再提取oz,并转换为g;体积单位优先提取ml,没有ml再提取fl oz,并转换为ml。

*注:1盎司(oz)=28.35克(g);1美制液体盎司(fl oz)=29.57毫升(ml)

因为重量单位和体积单位的不一致,为了之后的分析方便,我们假设1ml的液体等于1g,并把一些半液态和液态食品的份量从体积转为重量。

将食品调整至同样的份量(按100g计算)

#正则表达式匹配几种不同的份量标注方式
import re
p1 = re.compile(r'[(](.*?)[ g)]')
p2 = re.compile(r'(.*?)[ ]')

#定义函数,提取份量数据
def getLambda(x, p1, p2):
    try: 
        val = float(re.findall(p1,x)[0])
    except:
        val = float(re.findall(p2,x)[0]) * 29.57 # 提取的是fl oz,乘以29.57转换为ml
    return val

#调整menu数据集
norm_menu = menu.iloc[:,:]
norm_menu["Size g"] = norm_menu["Serving Size"].apply(lambda x: getLambda(x, p1, p2))
norm_menu["Calories per 100g"] = (norm_menu['Calories']/norm_menu["Size g"]) * 100

norm_menu.head()
#盒形图
fig, ax = plt.subplots(figsize = (12,9))
sns.boxplot(x = 'Category', y = 'Calories per 100g', data = norm_menu)

在这里插入图片描述

对比没有调整过的数据画出的盒形图可以得知:

  • 固态食品中,主食(早餐,牛肉猪肉,鸡肉鱼肉)依旧是卡路里含量最高的食品。之前我们以为卡路里含量较低的小食、甜点等,其实只是因为份量较小,如果换算成同样的份量,卡路里含量也不低,和主食持平。只有沙拉的卡路里含量远低于其他类食品,其平均值是主食的一半左右。
  • 液体及半液体的饮品,卡路里含量总体低于固体食品,但冰沙奶昔的卡路里明显高于饮料和咖啡茶,甚至高于沙拉。

因此,对于一个选择麦当劳就餐的减肥人士来说,为了填饱肚子,最好点一份沙拉。如果还想点一份饮品,不建议点冰沙奶昔。

4.4通过轮廓图和相关图来比较特征

轮廓图

我们首先看看一个特征如何影响其他特征:轮廓图或者KDE图可以提供一个特征相对于另一个特征的分布。简单来讲,这让我们对定量数据有一个快速的感知。调用了Seaborn中的kdeplot函数。我们选取了几个主要特征,并生成了9张轮廓图,如下所示:

# KDE图
f, axes = plt.subplots(3, 3, figsize=(10, 10), sharex=True, sharey=True)

s = np.linspace(0, 3, 10)
cmap = sns.cubehelix_palette(start=0.0, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Cholesterol (% Daily Value)'].values
y = menu['Sodium (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, cut=5, ax=axes[0,0])
axes[0,0].set(xlim=(-10, 50), ylim=(-30, 70), title = 'Cholesterol and Sodium')

cmap = sns.cubehelix_palette(start=0.333333333333, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Carbohydrates (% Daily Value)'].values
y = menu['Sodium (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[0,1])
axes[0,1].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Carbs and Sodium')

cmap = sns.cubehelix_palette(start=0.666666666667, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Carbohydrates (% Daily Value)'].values
y = menu['Cholesterol (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[0,2])
axes[0,2].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Carbs and Cholesterol')

cmap = sns.cubehelix_palette(start=1.0, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Total Fat (% Daily Value)'].values
y = menu['Saturated Fat (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[1,0])
axes[1,0].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Total Fat and Saturated Fat')

cmap = sns.cubehelix_palette(start=1.333333333333, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Total Fat (% Daily Value)'].values
y = menu['Cholesterol (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[1,1])
axes[1,1].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Cholesterol and Total Fat')

cmap = sns.cubehelix_palette(start=1.666666666667, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Vitamin A (% Daily Value)'].values
y = menu['Cholesterol (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[1,2])
axes[1,2].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Vitamin A and Cholesterol')

cmap = sns.cubehelix_palette(start=2.0, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Calcium (% Daily Value)'].values
y = menu['Sodium (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[2,0])
axes[2,0].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Calcium and Sodium')

cmap = sns.cubehelix_palette(start=2.333333333333, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Calcium (% Daily Value)'].values
y = menu['Cholesterol (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[2,1])
axes[2,1].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Cholesterol and Calcium')

cmap = sns.cubehelix_palette(start=2.666666666667, light=1, as_cmap=True)

# Generate and plot a random bivariate dataset
x = menu['Iron (% Daily Value)'].values
y = menu['Total Fat (% Daily Value)'].values
sns.kdeplot(x, y, cmap=cmap, shade=True, ax=axes[2,2])
axes[2,2].set(xlim=(-5, 50), ylim=(-10, 70),  title = 'Iron and Total Fat')


f.tight_layout()

在这里插入图片描述

Pearson相关图

现在绘制Pearson相关图,检查不同营养指标之间的相关程度。这次,我们调用了Plotly的交互式绘图功能,绘制特征之间相关性的热图(Heatmap),如下所示:

data = [
    go.Heatmap(
        z = menu.iloc[:, 3:].corr().values,
        x = menu.columns.values,
        y = menu.columns.values,
        colorscale = 'Viridis',
        text = menu.iloc[:, 3:].corr().round(2).astype(str),
        opacity = 1.0
    )
]

layout = go.Layout(
    title = '各个营养指标的Pearson相关图',
    xaxis = dict(ticks='', nticks=36),
    yaxis = dict(ticks=''),
    width = 900, height = 700,
)

fig = go.Figure(data = data, layout = layout)
py.iplot(fig, filename = 'labelled-heatmap')

在这里插入图片描述

点击不同的方格,可以查看某两个特征的相关性。颜色越趋近于黄色,说明两者正相关性越强。颜色越趋近于紫色,说明两者负相关性越强。

  • 从相关图中可以看出明显相关的特征,例如份量和卡路里的相关性高达0.9。
  • 然而,有一些相关性非常不直观。例如,总脂肪和饱和脂肪/反式脂肪之间存在相当弱的相关性,但在我们普通人的认知中,这两者理应早存一定相关性。
  • 热图也从负相关图(深蓝/黑)的斑点中引出了有趣的发现。例如,它表明碳水化合物通常与反式脂肪,胆固醇,钠,膳食纤维和维生素A呈负相关。这与碳水化合物的负相关性确实很多。

数据质量是否存在任何问题?

  • 现在很明显,碳水化合物列与其他列负相关程度很强,这是符合常识的。然而,或许存在如下可能性:含碳水化合物的食物可能除了碳水化合物之外没有其他东西,从而导致了上面提到的负相关性,这也是需要在分析中结合实际情况思考的。

订阅热门专栏:
《数据分析之道》
《数据分析之术》
《机器学习案例》
《数据分析案例》

📢文章下方有交流学习区!一起学习进步!💪💪💪
📢首发CSDN博客,创作不易,如果觉得文章不错,可以点赞👍收藏📁评论📒
📢你的支持和鼓励是我创作的动力❗❗❗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++模板整理

目录 一.泛型编程​​​​​​​ 二.函数模板 2.1 函数模板概念 2.2函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 三.类模板 3.1 类模板的定义格式 3.2 类模板的实例化 3.3模板类 一.泛型编程​​​​​​​ 如何实现一个通用的交…

【前端之旅】快速上手Echarts

一名软件工程专业学生的前端之旅,记录自己对三件套(HTML、CSS、JavaScript)、Jquery、Ajax、Axios、Bootstrap、Node.js、Vue、小程序开发(Uniapp)以及各种UI组件库、前端框架的学习。 【前端之旅】Web基础与开发工具 【前端之旅】手把手教你安装VS Code并附上超实用插件…

「高并发业务必读」深入剖析 Java 并发包中的锁机制

故事 程序员小张: 刚毕业,参加工作1年左右,日常工作是CRUD 架构师老李: 多个大型项目经验,精通各种屠龙宝术; 小张和老李一起工作已有数月,双方在技术上也有了很多的交流,但是却总是…

GB28181 协议 SIP

2、注册信令 2.1基本注册 2.1.1 抓包过程 2.1.2 详细步骤 2.1.2.1、REGISTER REGISTER sip:34020000002000000001192.168.9.186:15060 SIP/2.0Via: SIP/2.0/TCP 192.168.9.186:42860;rport;branchz9hG4bK1557586049From: <sip:30514805331320000140192.168.9.186:5060>…

手写Spring框架-前奏-反射获取Annotation

目录 所谓反射 反射机制的作用 反射依赖reflect和Class 反射依赖的Class Class类的特点 获取Class对象的三种方式 获取类的构造方法并使用 获取类的成员变量并使用 获取类的成员方法并使用 问题引入 解析类的注解 解析成员变量的注解标签 解析方法上的注解 注解获…

Java类加载

类加载的时机 一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期将会经历加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证、准备、解析三个阶段统称为连接。 图中加载、验证、准备、初始化和卸载这五个阶段的顺序是…

CDGP数据治理专家认证含金量如何?值得考一个吗?

CDGP&#xff08;Certified Data Governance Professional&#xff09;数据治理专家认证的含金量非常高。该认证证明了持有人拥有数据治理方面的专业知识和技能&#xff0c;能够有效地管理和保护组织的数据资产。 CDGP认证考试内容涵盖数据治理的各个方面&#xff0c;包括数据…

看这家在线教育企业如何通过DHTMLX Scheduler,实现培训管理系统优化

“我们公司目前有一套培训管理系统&#xff0c;用于管理培训学员。目前学员越来越多&#xff0c;老旧的系统已经没法满足需求&#xff0c;导致我们经常需要手动记录学员出勤培训情况&#xff0c;除此之外&#xff0c;系统课程安排只展示时间&#xff0c;没法展示诸如主题&#…

macOS Big Sur 11.7.6 (20G1231) 正式版 ISO、PKG、DMG、IPSW 下载

本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 Linux 中创建可引导介质。 2023 年 4 月 10 日&#xff08;北京…

【Vue全家桶】Pinia状态管理

【Vue全家桶】Pinia状态管理 文章目录【Vue全家桶】Pinia状态管理写在前面一、认识Pinia1.1 认识Pinia1.2 为什么使用Pinia&#xff1f;二、 Store2.1 定义Store2.2 Option对象2.3 setup函数2.4 使用定义的Store三、Pinia核心概念State3.1 定义State3.2 操作State3.3 使用选项式…

基于小生境粒子群优化算法的考虑光伏波动性的主动配电网有功无功协调优化(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

C语言基础——指针

文章目录一、指针1.指针的意义2.指针类型表示3.一些操作3.1打印1个变量地址3.2通过地址查看改地址的内容以及修改改地址的内容3.3操作某个空间 -- 4个字节,给他赋值为100&#xff0c;只知道该空间的地址0x8000 00004.指针变量的定义5.指针类型的大小6.指针变量的使用6.1 指针变…

python数据分析-matplotlib折线图知识总结01

python绘图库matplotlib的知识总结一.matplotlib是什么二.matplotlib的安装与导入三.matplotlib的常用函数四.matplotlib绘制折线图的使用方法1.设置图形大小2. 利用数据绘图3.调整x,y轴的刻度,旋转角度,显示描述信息,绘制网格,添加图例4.图形的样式5.绘制多条折线6.显示绘制的…

python知识记录:灵活使用numpy提高python数据分析效率!

NumPy是Python语言的一个第三方库&#xff0c;其支持大量高维度数组与矩阵运算。 作为python科学计算领域的三剑客之一&#xff0c;numpy在数据分析处理方面有着独特的魅力&#xff01; numpy模块的出现更多的是在数组处理的操作上面&#xff0c;并且支持和python常用的数据结…

Transformer在时序预测的应⽤第一弹——Autoformer

Transformer在时序预测的应⽤第一弹——Autoformer 原文地址&#xff1a;Autoformer: Decomposition Transformers with Auto-Correlation for Long-Term Series Forecasting&#xff08;NIPS 2021&#xff09; 做长时间序列的预测 Decomposition把时间序列做拆分&#xff0c…

目标检测——YOLOv7(十三)

简介&#xff1a; 继美团发布YOLOV6之后&#xff0c;YOLO系列原作者也发布了YOLOV7。主要从两点进行模型的优化&#xff1a;模型结构重参化和动态标签分配。 YOLOv7的特点是快&#xff01;相同体量下比YOLOv5精度更高&#xff0c;速度快120%&#xff0c;比YOLOX快180%。 Github…

RabbitMQ消息丢失的情况,以及如何通过代码解决

目录 RabbitMQ消息丢失问题&#xff1a; 代码部分&#xff1a; 完整代码&#xff1a; RabitMQConfig&#xff1a; CourseMQListener: 生产者跟交换机通信的消息丢失解决 &#xff1a; 交换机跟消息队列的消息丢失&#xff1a; 消息队列跟消费者的消息丢失&#xff1a; …

自动处理【支付宝交易支付投诉管理系统】配置指南

大家好&#xff0c;我是小悟 已经有小伙伴开始使用自动处理【支付宝交易支付投诉管理系统】&#xff0c;所以详细介绍一下如何配置。 阅读这篇文章之前&#xff0c;结合这篇【连夜干出来一个自动处理【支付宝交易支付投诉管理系统】&#xff0c;支持多商户】干货食用更佳。 连…

Filter 过滤器 Listener 监听器

Filter web中的过滤器当用户访问服务器资源时&#xff0c;过滤器将请求拦截下来&#xff0c;完成一些通用的操作应用场景如&#xff1a;登录验证、统一编码处理、敏感字符过滤 编写filter对目标资源servlet进行拦截 1. 编写java类&#xff0c;实现filter接口 public class Qu…

智慧医院人员定位系统解决方案,助力医院安全管理智能化

随着经济的发展与生活质量的提升&#xff0c;人们对医疗健康的重视度越来越高&#xff0c;医疗行业也因此蓬勃发展起来。然而&#xff0c;不断扩大的经营规模也给医院安全管理带来挑战和难题。 医院安全管理痛点 1、医疗事件信息获取不及时甚至存在瞒报现象&#xff0c;管理者…