Python数据分析:对饮食与健康数据的分析与可视化

2024.02前Python学习小结

1、 Python数据分析:对饮食与健康数据的分析与可视化
2、Python机器学习:Scikit-learn简单使用
3、Python深度学习:Tensorflow简单使用



前言

本文旨在对以往学习的相关内容进行总结回顾,通过seaborn对饮食与健康数据进行分析,侧重实现各数量间关系的可视化,因此具备以下特点:

  • 不苛求完全贴切,由于练习目的,不过多追求方法准确
  • 使用多种方法,对同样问题在保证准确情况下使用多种方法
  • 侧重任务描述,更像是说明书

一、数据说明

本文数据包含饮食习惯相关属性和身体状况相关属性,具体内容如下:

符号表示具体内容类别
FAVC频繁食用高热量食物饮食习惯相关
FCVC食用蔬菜频率饮食习惯相关
NCP主餐数量饮食习惯相关
CAEC两餐间食物消耗频率饮食习惯相关
CH2O每日饮水量饮食习惯相关
CALC饮酒量饮食习惯相关
SCC卡路里消耗监测身体状况相关
FAF身体活动频率身体状况相关
TUE使用技术设备时间身体状况相关
MTRANS使用交通工具身体状况相关
family…weight家庭成员超重史其他
NObeyesdad身体状况评价其他

身高、体重等简单介绍略,Excel文档一览:
Excel文档一览
数据分为饮食习惯相关和身体状况相关,并且包含不同年龄。首先想到统计对象组内分析和饮食习惯和年龄的组间关系。

原数据给出了身体状况评价指标(NObeyesdad),但未给出详细计算公式,因此计划用BMI反映身体状况,分析饮食习惯和身体状况间关系。所以总结起来,任务就是:

  • 统计样本对象特征
  • 饮食习惯间关系
  • 饮食习惯和身体状况间关系
  • 饮食习惯与身体状况间关系

二、数据清洗

1.相关库调用

导入相关库:

import numpy as np                ## 数据分析
import pandas as pd               ## 数据分析
import matplotlib.pyplot as plt   ## 画图
import seaborn as sns             ## 可视化

Seaborn的函数可选参数很多,图形简洁漂亮,往往一行就能生成热力图、散点图。

2.相关设置

设置数据小数点,忽略提醒,显示中文:

pd.options.display.float_format = '{:.2f}'.format#保留两位

import warnings                    ## 忽略提醒
warnings.filterwarnings('ignore')

#plt中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像显示为方块的问题

Matploblib默认无法使用中文,需要对中文进行设置,也可单独写个说明文件。刚开始使用时往往需要下载字体。可看这个(字体和本文程序放到本系列最后一个文档)

3.数据导入和清洗

导入数据,显示前五行观察是否导入成功

#数据导入
#df = pd.read_csv(r'D:\Pytharm\Practice\sjfenxilast\stib.csv')
df = pd.read_csv(r'stib.csv')#相对路径
#Check
print(df.head(5))

此处可使用相对路径或绝对路径。相对路径较好,当改变文件夹名时不用更改代码。
前五行显示

缺失与重复数据处理,此处最好再检查异常值的,这一步放后面了

#检查重复项和缺少值
print("\033[1;37m检查重复项和缺失值\033[0m")
print(f'\033[94mNumber of records/rows & features/columns in the dataset are: {df.shape[0], df.shape[1]}')
print(f'\033[94mNumber of duplicate entries in the dataset are: {df.duplicated().sum()}')
print(f'\033[94mNumber missing values in the dataset are: {sum(df.isna().sum())}')

## 删除重复项
df.drop_duplicates(keep='first',inplace=True)

## 再次检查
print("\033[1;37m再次检查\033[0m")
print(f'\033[94mNumber of records/rows & features/columns in the dataset are: {df.shape[0], df.shape[1]}')
print(f'\033[94mNumber of duplicate entries in the dataset are: {df.duplicated().sum()}')

为显示方便可设置文字颜色,具体见Python内容颜色输出。
再次检查不存在重复和缺失
第一次检查,存在24个重复项,不存在缺失值,因此仅对重复项进行处理。
如存在缺失值可使用以下代码进行处理:

## 检查缺失值
missing_val = df.isnull().sum()[df.isnull().sum() > 0]
print('missing values by feature')
print(missing_val)
missing_val_prc = missing_val / len(df)*100
print('missing values by feature, by % of total')
print(missing_val_prc)

若missing_val_prc(缺失比例)较少则直接舍去,太多就得考虑插入了。

检查数据类型

df.info()

为了查看数据是否存在空值以及确定数据类型方便后续操作。
数据类型
相关数据无空值,处理完成。注意到年龄是float类型,可能存在很多小数,若建立年龄的相关分析得注意处理。对于数字型尽量不要弄成标签。

相关设置

#seaborn的颜色设置,或者直接用白色主题
#sns.set(style=’white‘)
sns.set(rc={'axes.facecolor':'none','axes.grid':False,'xtick.labelsize':7,'ytick.labelsize':7,
            'figure.autolayout':True, 'figure.dpi':180, 'savefig.dpi':180})
my_col = ('#40E0D0', '#D2B48C','#c7e9b4', '#EEE8AA','#00FFFF','#FAEBD7','#FF6347', 
          '#FAFAD2', '#E0EEEE', '#C1CDCD', '#838B8B', '#D8BFD8','#F4A460',
          '#F08080', '#EE82EE', '#4682B4','#6A5ACD', '#00C78C', '#FFB6C1', '#8B5F65')

seaborn支持内置的显示风格,黑白什么的,见风格设置。本文直接设置col块并且手动初始化设置。

三、青年人饮食习惯分析

1.样本分析

为分析青年人饮食习惯,首先对统计对象进行简单查看。

df['Age'] = df['Age'].apply(int)
#First,年龄、性别分布统计图
plt.figure(figsize=(12,9))
plt.subplot(211)
plt.title('Gender', color='#8B5A2B', weight='bold', fontsize=14,fontproperties="SimHei")
sns.countplot(x=df['Gender'])

plt.subplot(212)
plt.title('Age',color='green', weight='medium', fontsize = 8,fontproperties="SimHei")
sns.countplot(df['Age'].value_counts().sort_values(), color='g', linewidth = 1)
sns.countplot(x='Age',data=df)
plt.savefig('性别年龄统计分布图',bbox_inches='tight')
plt.show()

由于看到年龄存在很多小数,首先对年龄取int型,忽略小数部分。样本主要特征是年龄和性别,查看两者属性分布:
性别年龄分布
可以看到男女比例基本相同,年龄大多分布在30岁以下,由此想到舍去30以上数据,做青年人相关分析。男女比例基本相同也不必再分两个样本了。

2.具体内容

分析青年人群饮食习惯

#Second,青年人饮食习惯与年龄,不同年龄饮水量CH2O、高热量食物FAVC、食用蔬菜FCVC
#取30岁以下为研究对象
pd30 = df[df['Age'] < 31]
plt.figure(figsize=(12,9))
plt.subplot(421)
plt.title('Age',color='green', weight='medium', fontsize = 5,fontproperties="SimHei")
sns.countplot(pd30['Age'].value_counts().sort_values(), color='g', linewidth = 1)
sns.countplot(x='Age',data=pd30)
#sns.stripplot(x = 'Age',y = pd30['Age'].value_counts().sort_values(),data = pd30)
#sns.barplot(y = pd30['Age'].value_counts().sort_values(),x = 'Age',data = pd30,estimator= np.max)


plt.subplot(422)
plt.title('FAVC',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.countplot(x=pd30['Age'], hue=pd30['FAVC'], palette=my_col, edgecolor = "black", saturation=1)
#sns.catplot(x="Gender", y="Age",hue="CH2O", col="FAVC",data=pd30, kind="bar",height=4, aspect=.7)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(423)
plt.title('FCVC',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.countplot(x=pd30['Age'], hue=pd30['FCVC'], palette=my_col, edgecolor = "black", saturation=1)
#sns.barplot(x="day", y="total_bill", hue="sex", data=tips)

plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(424)
plt.title('CH2O',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.countplot(x=pd30['Age'], hue=pd30['CH2O'], palette=my_col, edgecolor = "black", saturation=1)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)
plt.savefig('青年人饮食习惯统计图',bbox_inches='tight')
plt.show()

# 喝水喝酒关系
plt.figure(figsize=(12,9))
sns.catplot(x="Gender", y="Age",hue="CH2O", col="FCVC",data=pd30, kind="bar",height=4, aspect=.7)
plt.savefig('喝水和喝酒关系')
plt.show()

首先将原数据进行展示,在比较几个指标间关系时,可选择条形图、密度图、散点图等。本文数据量较少可选柱状图、密度图,数据多散点图较好。注释部分为分类散点图
各饮食习惯与年龄关系

  1. 统计对象集中在21岁附近
  2. 各年龄段都中大多数人有食用高热量食物习惯
  3. 除25、26岁人群外,大多一天吃两次蔬菜。很少只吃一次蔬菜。
  4. 大多数人一天喝两次水

喝水量与喝酒量间关系

喝水喝酒关系

  1. 常喝水的女性不会喝酒
  2. 其他喝水状况女性和喝酒基本无关

本节也尝试了其他几类图像(文章程序无下图代码,均以饮食量为例,图一:displot)
几类图片

四、青年人身体状况分析

1.指标选取

本节旨在反映样本身体状况。首先需要界定评价指标。
为反映各样本身体状况,自定义BMI=体重/身高平方,低于18.5为low…略然后分析各年龄段身体状况分布。

产生评价指标

#Second,青年人身体状况,不同年龄卡路里消耗SCC、身体活动频率FAF、BMI
#BMI,BMI等于体重比身高,小于18.5过低,18.5到24正常,24到28超重,28以上肥胖
pd30['BMI']=((pd30['Weight'])/(pd30['Height']**2)).round(1)
print(np.mean(pd30['BMI']))
print(np.mean(pd30['Weight']))
print(np.mean(pd30['Height']))
#创建BMIex作为BMI评价
pd30['BMIex'] = ''
pd30.loc[pd30['BMI'] <= 18.5, 'BMIex'] = 'low'
pd30.loc[(pd30['BMI'] > 18.5) & (pd30['BMI']<=24),'BMIex'] = 'Normal'
pd30.loc[pd30['BMI'] > 24 & (pd30['BMI'] <= 28), 'BMIex'] = 'Overweight'
pd30.loc[pd30['BMI'] > 28, 'BMIex'] = 'Fat'

#FAF有很多小数得转化为几个整数形成标签
pd30['FAFex'] = ''
pd30.loc[pd30['FAF'] <= 0, 'FAFex'] = 'Seldom'
pd30.loc[(pd30['FAF'] > 0) & (pd30['FAF']<=2),'FAFex'] = 'Sometime'
pd30.loc[pd30['FAF'] > 2, 'FAFx'] = 'Frequently'

由于统计只能使用文本格式标签,需要将FAF形成文本内容。产生的BMIex指标和文档内给定指标(NObeyesdad)不同。

2.具体内容

统计各指标分布

## 画图,活动频率
plt.figure(figsize=(12, 9))

plt.subplot(311)
plt.title('SCC',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
#sns.countplot(x=pd30['Age'], hue=pd30['SCC'], palette=my_col, edgecolor = "black", saturation=1)
sns.histplot(data=pd30,x=pd30['Age'],
             hue="SCC",  # 分组
             stat="density",  # 密度图(y轴刻度)
             element="poly")  # 控制密度图显示方式
plt.xlabel(None), plt.ylabel(None)

plt.subplot(312)
plt.title('FAFex',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
#sns.countplot(x=pd30['Age'], hue=pd30['FAFex'], palette=my_col, edgecolor = "black", saturation=1)
sns.histplot(data=pd30,x=pd30['Age'],
             hue="FAFex",  # 分组
             stat="density",  # 密度图(y轴刻度)
             element="poly")  # 控制密度图显示方式
plt.xlabel(None), plt.ylabel(None)

plt.subplot(313)
plt.title('BMIex',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.countplot(x=pd30['Age'], hue=pd30['BMIex'], palette=my_col, 
plt.legend(loc='upper right', fontsize=7)
edgecolor = "black", saturation=1)
plt.xlabel(None), plt.ylabel(None)
plt.savefig('青年人身体状况',bbox_inches='tight')
plt.show()

注意对直方图不可使用plt.legend设置图例,因为直方图通常用于表示单个变量的分布,而不涉及多个数据系列的比较。
身体状况统计图

  1. 基本都不会做卡路里监测
  2. 22岁以下人群更多是偶尔(Sometime)运动
  3. 经常运动(Always)人较少
  4. 统计人群按照BMI惯例计算均超重,为此对相关数据进一步监测(数据清洗部分做过基本不会大问题)

3.身高体重数据检查

对数据分布可使用箱线图,小提琴图等进行观察,本部分主要使用箱线图。箱线图有给出数据误差等信息,方便排除异常值。

#居然没有正常的,身高体重数据很可能有问题检查一下,该部分方法很多,多尝试几个
plt.figure(figsize=(12,9))
plt.subplot(221)
plt.title('Weight',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.boxplot(x="Gender",y="Weight",hue="BMIex", data=pd30)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(222)
plt.title('Height',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.boxplot(x="Gender",y="Height",hue="BMIex", data=pd30)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(223)
plt.title('Height',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.boxenplot(x="Gender", y="Height",color="orange",hue = "BMIex", scale="linear", data=pd30)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(224)
plt.title('Weight',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.boxenplot(x="Gender", y="Weight",color="orange",hue = "BMIex", scale="linear", data=pd30)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)
plt.savefig('身高体重数据',bbox_inches='tight')
plt.show()

箱形图

  1. 基本没异常值
  2. 3、4图是“信值图”,显示了大量被定义为“置信区间”的分位数,适合大量数据。具体说明见箱线图
  3. 过重和肥胖数据差异不大

可对置信区间外数据进行删除

#删除异常值
wQ1 = pd30['Weight'].quantile(0.25)
wQ3 = pd30['Weight'].quantile(0.75)
wIQR = wQ3 - wQ1
lower_bound = wQ1 - 1.5 * wIQR
upper_bound = wQ3 + 1.5 * wIQR
#outliers = pd30['Weight'][(pd30['Weight'] < lower_bound) | (pd30['Weight'] > upper_bound)]
#pd30_new = pd30['Weight'][~((pd30['Weight'] < lower_bound) | (pd30['Weight'] > upper_bound))]
#pd30_new = df[df['Age'] < 31]
pd30_new = pd30[pd30['Weight'] < lower_bound & pd30['Weight']>upper_bound]

plt.figure(figsize=(12,9))
plt.subplot(221)
plt.title('Weight',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
#sns.boxplot( y=pd30['Weight'] )
sns.boxplot(x="Gender",y="Weight",hue="BMIex", data=pd30_new)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)
plt.show()

五、几个相关性

最后对几个属性间相关信进行分析

#作热力图需转换为数值型
#pd30.loc[pd30['NCP'] == 'One', 'NCPnum'] = 1
#pd30.loc[pd30['NCP'] == 'Two', 'NCPnum'] = 2
#pd30.loc[pd30['NCP'] == 'Three', 'NCPnum'] = 3

#几个相关性,热力图部分未画可看注释
#pd30_FAFNCP = pd30[['FAF','NCPnum','Height']] ## 热力图需形成新数组

plt.figure(figsize=(12,9))
plt.subplot(221)
plt.title('交通工具和体重',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
#sns.boxplot( y=pd30['Weight'] )
#sns.swarmplot(x="MTRANS",y="Age",data=pd30)
sns.swarmplot(x=pd30["MTRANS"], y=pd30["Weight"],hue=pd30['BMIex'],data=pd30)
#plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(222)
plt.title('活动频率和身高',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
#sns.stripplot(x="SCC",y="Age",data=pd30)
sns.swarmplot(x=pd30["FAF"], y=pd30["Height"],hue = pd30['BMIex'], data=pd30)
#plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

"""
## 热力图,最后是两个多值数组,本数据FAF才3个值不好看
plt.subplot(223)
plt.title('sj',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.heatmap(pd30_FAFNCP,vmin=0,vmax=1)
plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)
"""

plt.subplot(223)
plt.title('主餐数量和身高',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.violinplot(x=pd30["NCP"], y=pd30["Height"])
#plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)

plt.subplot(224)
plt.title('主餐数量和体重',color='#8B5A2B', weight='medium', fontsize=5,fontproperties="SimHei")
sns.violinplot(x=pd30["NCP"], y=pd30["Weight"])
#plt.legend(loc='upper right', fontsize=7)
plt.xlabel(None), plt.ylabel(None)
plt.savefig('几个相关性',bbox_inches='tight')
plt.show()

上图使用散点图,下图使用小提琴图。小提琴图更能反映数据内关系。
相关性图

  1. 高体重人群更喜好使用公共交通工具
  2. 活动多人群体重相对更好
  3. 吃四次主餐人群平均身高更高,且体重更低

总结

本文通过饮食习惯与身体健康指标练习了seaborn相关函数使用。涉及基本数据清洗,数据分析、可视化内容,是对本科阶段Python数据分析学习的小结。

自学之路颇多弯路,笔者既因一次次错误而懊悔,也因一次次尝试后发现新的路径而快乐,探索而乐在其中。笔者是电气专业,对我而言,数据分析能力注定只能成为工具,也将以切实、高效使用为目的。

这是第一篇编程类文章分享,也期待26号的研究生出分顺利!

  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python数据分析是利用Python编程语言进行数据分析的过程。在数据分析中,经常需要将分析的结果进行可视化展示,提供更直观的信息呈现。而基于plotly的动态可视化绘图则是一种利用plotly库进行数据绘图,并且实现动态效果的方法。plotly是一个强大的绘图库,它可以绘制各种类型的图表,并且支持交互式操作,使得数据分析结果更加直观。 绘制动态可视化图表的过程如下:首先,需要安装plotly库,并导入相应的模块。然后,根据需要,选择合适的图表类型,比如折线图、散点图等,利用plotly的绘图函数进行绘制。可以设置图表的布局、颜色、标题等属性,使得图表更具美观性和可读性。接下来,根据数据的变化,通过更新数据源或设置动画效果,实现图表的动态效果。最后,将生成的图表保存为PDF格式的文件,方便保存和分享。 使用基于plotly的动态可视化绘图有以下几个优点:首先,plotly的绘图功能十分强大,可以绘制各种类型的图表,并且支持交互式操作,方便用户进行数据探索和分析。其次,动态可视化图表可以更加生动地展示数据的变化趋势和关系,增加了数据分析的直观性和可理解性。此外,生成的图表可以保存为PDF格式的文件,方便与他人分享和使用。 总之,基于plotly的动态可视化绘图可以帮助数据分析人员更好地展示分析结果,提供直观的信息呈现。它是数据分析中非常有用的工具之一,能够提升数据分析的效果和表现力。 ### 回答2: Python数据分析是利用Python编程语言进行数据分析的一种方法。其中,基于plotly的动态可视化绘图是指使用plotly库来创建具有交互性和动态效果的图表。而动态可视化绘图的优势在于能够更直观地展示数据的变化趋势和关联性。 在使用Python进行数据分析时,绘制可视化图表是非常重要的步骤之一。而plotly作为一种强大的可视化库,提供了丰富的图表类型和交互特性,能够满足各种数据分析的需求。通过使用plotly,用户可以绘制条形图、折线图、散点图、饼图等各种常见图表,并且可以根据需要添加交互功能,如缩放、悬停等。 与传统的静态图表不同,动态可视化图表能够更好地展示数据的变化。例如,在时间序列数据分析中,绘制动态折线图可以使用户更直观地看到数据随时间的变化趋势。此外,通过添加滑块或按钮等控件,用户可以通过切换控件的状态来查看不同时间点的数据情况,进一步加深对数据的理解。 绘制动态可视化图表并将其保存为PDF格式可以方便用户在不同设备上查看和分享。Python的绘图库可以轻松实现将图表保存为PDF文件的功能。只需使用相应的函数将绘制的图表对象保存为PDF文件即可。这样,数据分析人员可以将生成的动态可视化图表以PDF的形式分享给其他人,实现对数据分析过程和结果的可视化共享。 总结来说,基于plotly的动态可视化绘图是一种强大的数据分析工具,能够通过交互性和动态效果更好地展示数据分析的结果。将绘制的图表保存为PDF文件可以方便用户在不同设备上查看和分享。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值