复习:回顾学习完第一章,我们对泰坦尼克号数据有了基本的了解,也学到了一些基本的统计方法,第二章中我们学习了数据的清理和重构,使得数据更加的易于理解;今天我们要学习的是第二章第三节:数据可视化,主要给大家介绍一下Python数据可视化库Matplotlib,在本章学习中,你也许会觉得数据很有趣。在打比赛的过程中,数据可视化可以让我们更好的看到每一个关键步骤的结果如何,可以用来优化方案,是一个很有用的技巧。

2 第二章:数据可视化¶

开始之前,导入numpy、pandas包和数据¶

In [1]:
# 加载所需的库
# 如果出现 ModuleNotFoundError: No module named 'xxxx'
# 你只需要在终端/cmd下 pip install xxxx 即可
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

导入result.csv这个文件

In [2]:
text = pd.read_csv(r'result.csv')
text.head()
Out[2]:
Unnamed: 0 PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 0 1 0 3 Braund, Mr. Owen Harris male 22.0 1.0 0.0 A/5 21171 7.2500 NaN S
1 1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1.0 0.0 PC 17599 71.2833 C85 C
2 2 3 1 3 Heikkinen, Miss. Laina female 26.0 0.0 0.0 STON/O2. 3101282 7.9250 NaN S
3 3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1.0 0.0 113803 53.1000 C123 S
4 4 5 0 3 Allen, Mr. William Henry male 35.0 0.0 0.0 373450 8.0500 NaN S

2.7 如何让人一眼看懂你的数据?¶

《Python for Data Analysis》第九章

2.7.1 任务一:跟着书本第九章,了解matplotlib,自己创建一个数据项,对其进行基本可视化¶

【思考】最基本的可视化图案有哪些?分别适用于那些场景?(比如折线图适合可视化某个属性值随时间变化的走势)

最基本的可视化图案及其适用场景如下:

  1. 折线图 (Line Chart)

    • 适用场景:展示数据随时间或连续变量的变化趋势。例如,股票价格随时间的变化、温度变化趋势等。
  2. 柱状图 (Bar Chart)

    • 适用场景:比较不同类别的数据大小。例如,不同城市的销售额、男女生存人数对比等。
  3. 饼图 (Pie Chart)

    • 适用场景:展示数据在整体中的比例分布。例如,市场份额占比、人口比例等。
  4. 散点图 (Scatter Plot)

    • 适用场景:显示两个变量之间的关系或分布。例如,身高与体重的关系、年龄与收入的关系等。
  5. 直方图 (Histogram)

    • 适用场景:展示数据的分布情况,特别是连续变量的频率分布。例如,年龄分布、考试成绩分布等。
  6. 箱线图 (Box Plot)

    • 适用场景:展示数据的分布特征,包括中位数、四分位数及异常值。例如,工资水平的分布、实验数据的离散程度等。
  7. 热力图 (Heatmap)

    • 适用场景:展示数据的相关性或强度。例如,相关性矩阵、地理数据的热度分布等。
  8. 面积图 (Area Chart)

    • 适用场景:展示随时间变化的累积数据。例如,累计销售额、累计用户增长等。
  9. 雷达图 (Radar Chart)

    • 适用场景:比较多维数据的表现。例如,不同产品的性能对比、运动员的能力评估等。
  10. 气泡图 (Bubble Chart)

    • 适用场景:展示三个变量之间的关系。例如,收入、支出与人口的关系。

选择合适的图表类型取决于数据的特性和想要传达的信息。

思考回答¶

这一部分需要了解可视化图案的的逻辑,知道什么样的图案可以表达什么样的信号¶

2.7.2 任务二:可视化展示泰坦尼克号数据集中男女中生存人数分布情况(用柱状图试试)。¶

In [3]:
# 将数据按“Sex”(性别)分组,然后对每组的“Survived”(是否存活,1为存活,0为死亡)进行求和。
sex = text.groupby('Sex')['Survived'].sum()
# 使用条形图(bar plot)来可视化每个性别的存活人数。
sex.plot.bar()
plt.title('survived_count')
plt.show()
No description has been provided for this image

【思考】计算出泰坦尼克号数据集中男女中死亡人数,并可视化展示?如何和男女生存人数可视化柱状图结合到一起?看到你的数据可视化,说说你的第一感受(比如:你一眼看出男生存活人数更多,那么性别可能会影响存活率)。

In [4]:
# 按性别分组,统计死亡人数(Survived为0表示死亡)
# 对每个分组的 Survived 列应用一个函数:lambda x: (x==0).sum()。
# 其中 x==0 会生成一个布尔序列,表示每个样本是否死亡(死亡为 True)。
# .sum() 会统计 True 的个数,也就是死亡人数。
death = text.groupby('Sex')['Survived'].apply(lambda x: (x==0).sum())
death.plot.bar()
plt.title('Death Count by Sex')
plt.ylabel('Death Count')
plt.show()
No description has been provided for this image

2.7.3 任务三:可视化展示泰坦尼克号数据集中男女中生存人与死亡人数的比例图(用柱状图试试)。¶

In [5]:
# 提示:计算男女中死亡人数 1表示生存,0表示死亡

# text.groupby(['Sex','Survived'])['Survived'].count().unstack().plot(kind='bar',stacked='True') 
# 上述长语法可以拆解成以下几步:
# 1. 按性别和生存状态分组,统计每组的样本数量
grouped = text.groupby(['Survived','Sex'])['Survived'].count()
# grouped = text.groupby(['Sex','Survived'])['Survived'].count()

# 2.把分组结果转换成以性别为行、生存状态为列的表格
table = grouped.unstack()
print(table)
# 3.使用堆积条形图来可视化不同性别的生存和死亡人数   
#  stacked=True 参数用于生成“堆积图”
table.plot(kind='bar', stacked=True)
# 下面两个语法是等价的 你可以取消注释看看不加stacked=True的效果
# table.plot.bar()  == table.plot(kind='bar') 


plt.title('survived_count')
plt.ylabel('count')
Sex       female  male
Survived              
0             81   468
1            233   109
Out[5]:
Text(0, 0.5, 'count')
No description has been provided for this image

table = grouped.unstack()思考:这行代码的作用是什么?为什么要用unstack()方法?如果不使用unstack()方法,结果会有什么不同? 进一步理解unstack()方法。

【提示】男女这两个数据轴,存活和死亡人数按比例用柱状图表示

2.7.4 任务四:可视化展示泰坦尼克号数据集中不同票价的人生存和死亡人数分布情况。(用折线图试试)(横轴是不同票价,纵轴是存活人数)¶

【提示】对于这种统计性质的且用折线表示的数据,你可以考虑将数据排序或者不排序来分别表示。看看你能发现什么?

In [6]:
# 计算不同票价中生存与死亡人数 1表示生存,0表示死亡
# 以票价(Fare)为分组依据,对每个票价下的“Survived”列进行分组。
# 按照人数从大到小排序,方便观察票价分组下生还/死亡人数最多的情况。
fare_sur = text.groupby(['Fare'])['Survived'].value_counts().sort_values(ascending=False)
fare_sur
Out[6]:
Fare      Survived
8.0500    0           38
7.8958    0           37
13.0000   0           26
7.7500    0           22
13.0000   1           16
                      ..
6.9750    0            1
90.0000   0            1
113.2750  0            1
6.9500    0            1
135.6333  0            1
Name: count, Length: 330, dtype: int64

.count() 和 .value_counts() 有什么区别

.count() 和 .value_counts() 都是 pandas 中常用的统计方法,但它们的作用不同:

  • .count()
    统计某一列(或分组后某一列)非空(非NaN)值的数量。
    常用于 DataFrame 或 Series,返回的是“有多少个有效值”。

  • .value_counts()
    统计每个不同取值出现的次数(频数分布)。
    只用于 Series,返回每个唯一值及其出现的次数,常用于分类变量分析。

举例说明:

s = pd.Series([1, 2, 2, 3, 3, 3, np.nan])
s.count()         # 结果是6,统计非NaN的数量
s.value_counts()  # 结果是:3出现3次,2出现2次,1出现1次

总结:

  • .count() 得到“总数”
  • .value_counts() 得到“每个值的频数”
In [7]:
# 排序后绘折线图
fig = plt.figure(figsize=(20, 18)) # 创建画布
fare_sur.plot(grid=True) # 对 fare_sur 这个 Series 画图,并显示网格线。
plt.legend()
plt.show()
No description has been provided for this image
In [8]:
# 排序前绘折线图
fare_sur1 = text.groupby(['Fare'])['Survived'].value_counts()
fare_sur1
Out[8]:
Fare      Survived
0.0000    0           14
          1            1
4.0125    0            1
5.0000    0            1
6.2375    0            1
                      ..
247.5208  1            1
262.3750  1            2
263.0000  0            2
          1            2
512.3292  1            3
Name: count, Length: 330, dtype: int64
In [9]:
fig = plt.figure(figsize=(20, 18))
fare_sur1.plot(grid=True)
plt.legend()
plt.show()
No description has been provided for this image

2.7.5 任务五:可视化展示泰坦尼克号数据集中不同仓位等级的人生存和死亡人员的分布情况。(用柱状图试试)¶

In [10]:
# 1表示生存,0表示死亡
pclass_sur = text.groupby(['Pclass'])['Survived'].value_counts()
pclass_sur
Out[10]:
Pclass  Survived
1       1           136
        0            80
2       0            97
        1            87
3       0           372
        1           119
Name: count, dtype: int64
In [11]:
# %pip install seaborn
In [12]:
import seaborn as sns
sns.countplot(x="Pclass", hue="Survived", data=text)
Out[12]:
<Axes: xlabel='Pclass', ylabel='count'>
No description has been provided for this image

【思考】看到这个前面几个数据可视化,说说你的第一感受和你的总结

In [13]:
#思考题回答

2.7.6 任务六:可视化展示泰坦尼克号数据集中不同年龄的人生存与死亡人数分布情况。(不限表达方式)¶

In [14]:
facet = sns.FacetGrid(text, hue="Survived",aspect=3)
facet.map(sns.kdeplot,'Age',shade= True)
facet.set(xlim=(0, text['Age'].max()))
facet.add_legend()
c:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\seaborn\axisgrid.py:854: FutureWarning: 

`shade` is now deprecated in favor of `fill`; setting `fill=True`.
This will become an error in seaborn v0.14.0; please update your code.

  func(*plot_args, **plot_kwargs)
c:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\seaborn\axisgrid.py:854: FutureWarning: 

`shade` is now deprecated in favor of `fill`; setting `fill=True`.
This will become an error in seaborn v0.14.0; please update your code.

  func(*plot_args, **plot_kwargs)
Out[14]:
<seaborn.axisgrid.FacetGrid at 0x220dafdb310>
No description has been provided for this image

2.7.7 任务七:可视化展示泰坦尼克号数据集中不同仓位等级的人年龄分布情况。(用折线图试试)¶

In [15]:
# 绘制“核密度估计曲线”(Kernel Density Estimation,简称KDE)。
# 是一种平滑的概率密度曲线,用于展示数据的分布情况,比直方图更平滑、连续。
text.Age[text.Pclass == 1].plot(kind='kde')
text.Age[text.Pclass == 2].plot(kind='kde')
text.Age[text.Pclass == 3].plot(kind='kde')
plt.xlabel("age")
# 添加图例,分别标注1、2、3,代表不同的舱位等级,loc="best"让图例自动选择合适的位置
plt.legend((1,2,3),loc="best")
Out[15]:
<matplotlib.legend.Legend at 0x220db3120d0>
No description has been provided for this image

【思考】上面所有可视化的例子做一个总体的分析,你看看你能不能有自己发现

In [16]:
#思考题回答

【总结】到这里,我们的可视化就告一段落啦,如果你对数据可视化极其感兴趣,你还可以了解一下其他可视化模块,如:pyecharts,bokeh等。

如果你在工作中使用数据可视化,你必须知道数据可视化最大的作用不是炫酷,而是最快最直观的理解数据要表达什么,你觉得呢?