![Python统计可视化之Altair探索分析实践指南(全彩版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/400/43738400/b_43738400.jpg)
1.5 Pandas的数据框(DataFrame)对象的使用方法
在Altair中,使用的数据集要以“整洁的格式”加载。这就需要将原始数据整理成适当的数据结构,才可以使用Altair的API、实例方法和类进行各种场景的分类汇总及统计分组。其中,分类汇总就是统计学中的描述统计,例如,均值、标准差、最大值、最小值、中位数、分位数、计数(count)和求和(sum)等。因此,整洁的数据格式是Altair需要的数据结构,同时,整洁的数据格式也是实现统计可视化的必要环节。Pandas中的DataFrame是Altair使用数据集的数据结构之一。
DataFrame是一种类似Excel或SPSS的表格型数据结构,DataFrame既有行索引,也有列索引,每一行是一个观察记录(case/observation),每一列是一个变量的不同取值(variable values)。创建DataFrame主要使用Python中的字典。下面,我们通过示例说明具体的实现方法。
1.5.1 使用字典创建DataFrame的方法
(1)导入Pandas。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/028-1.jpg?sign=1739425800-IuYfNCbLGOOWsKWin6FryRLJirAwQ1PM-0-8a41c8072c0753b609af135070ea366a)
(2)定义一个变量,用来存储字典。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/028-2.jpg?sign=1739425800-H3rKITgUobr3TkF8kOjvSzXYDfMZ0VZc-0-75d485c7ff9a882dc7dcce46cc9d4bbe)
(3)生成Pandas中的DataFrame。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/028-3.jpg?sign=1739425800-ORu1pXXzaKBqS6gazhIYraGf7QZhpsFO-0-e27a4a5805d54b1fed473ecc838243da)
如果需要查看某些变量的取值情况,则可以给DataFrame增加列索引;如果需要查看某些案例(cases),也称为观测记录(observations),即样本(samples),还可以增加行索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-2.jpg?sign=1739425800-DwatXPDbRO253RjNCJO7zlLfhd73alis-0-f05a1d3c7c2015dbb19dc8b2bae116d4)
注意:输出结果中的第1列不是索引数(即下标),而是关键字参数index列表中的元素。由于下标和目前列表中的元素(0和1)相同,可能会误以为它们是一样的。如果查看第3行的观测记录,则可以使用df.loc["two"],但不可以使用df.loc[2]。
如果列索引的字符串不是字典中的键,那么生成的DataFrame中的相应变量的取值就是空值(NaN),例如,使用字符串"name"作为列表columns中的元素。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-3.jpg?sign=1739425800-m3s9U50i41IdlFyMNgXbvVdLZxB10Jh0-0-d9a9bfa5a8a0362e864f31b4f9c39ee7)
1.5.2 DataFrame的操作方法
对DataFrame而言,可以选择某一列或若干列、某一行或若干行、某一个值或若干个值,也可以查看行索引、列索引、值区域。
下面使用以下代码生成DataFrame,存储在变量df里。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-4.jpg?sign=1739425800-pwWmDuqnZv8nZr211LoocBktC7d2ul3t-0-445cb6ba6e16bca840b44522f249b0bc)
查看行索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-5.jpg?sign=1739425800-NSXg6R3oYaRJm5F4zaHnC3HXZt66aPjs-0-9e3372eece182331351dbbfea59a7afd)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-1.jpg?sign=1739425800-QOvyqdXBTLOXZYWWr3nyJt4XgsLSprgf-0-61584ceebc6d500e34816a91c191ae96)
查看列索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-2.jpg?sign=1739425800-1DcDimmWIToCwKYbrVwN1f2dGz6suRNu-0-a407096bde1e5301ec3f614444a6c9fc)
查看值区域,也就是不包含行索引和列索引,这是一个二维数组,行和列的索引起始值都是0。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-3.jpg?sign=1739425800-mFnD0HguUU6lgp2njK6cMWXb6xZAC254-0-6aaf45fac34df42b50f1accf4da70022)
查看某一列和若干列。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-4.jpg?sign=1739425800-Dju1X5MJRj1oc7qg7IdJ60qh4Orz5ygI-0-4111a5c5074eeedaab868bf8f074742f)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-1.jpg?sign=1739425800-VD4ghlFZ4r0JuEkWbJjcykCAnSLuip63-0-a57f24f54f8860cbd74e060bd0264ab9)
注意:选择若干列需要将列索引中的元素放在列表中,从而产生双列表。
查看某一行和若干行。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-2.jpg?sign=1739425800-eFap75OlVqU0SXoAmktGLDYYIivOmYI9-0-e9c98b655f070b65c4d983bcc95450eb)
注意:选择若干行需要将行索引中的元素放在列表里,从而产生双列表。
查看某一个值和若干个值。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-3.jpg?sign=1739425800-C1WGwfAesTbxt2kggwM4ftrTtUa5W4B1-0-34487f6c2c3594788064bcc4d17472bd)
1.5.3 缺失值的操作方法
对于DataFrame而言,缺失值的识别和处理可以使用Pandas。缺失值的识别和处理是数据清理的重要环节。因此,高效、简便地识别方法和处理流程就显得尤为关键。可以从某一列或若干列、某一行或若干行、某一个值或若干个值等环节入手,高效识别缺失值。
1. 识别缺失值
使用API函数isna()或isnull()可以判断数据框(DataFrame)对象的变量取值是否存在缺失值。使用方法如下所示。
(1)导入需要的包。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-1.jpg?sign=1739425800-VEw1cbWPwns99KKZasQEtHdrCmkWJFTO-0-6f7c8baa43c1c57aa40215002dde95d8)
(2)加载数据集cars。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-2.jpg?sign=1739425800-cm1jIDYYTGqAJulYQRRbVVcZ01pOeyKt-0-734eb379f16077015dff016a239ee38d)
(3)判断变量取值是否存在缺失值。输出结果如图1.4和图1.5所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-3.jpg?sign=1739425800-L2Z5e0TznrebkmlwaYUS6nlNkMtB7Hq9-0-60e51dd2b95b3ece6f90fc2ec283fefa)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-01.jpg?sign=1739425800-TEVN8wOPMywv6J2wWJuvmr2U31f60TZW-0-3bcc6e23b655b577d15b1ff677f7760a)
图1.4
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-4.jpg?sign=1739425800-sog4vhj0Jgc54gfXTHbLfxlb8DkeByxy-0-c09387248dde3a35c1b5b4822eefbd5d)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-01.jpg?sign=1739425800-XA8RCO0NSFRx1RIEVwlSmERbLpcw85HG-0-a0d1b014536a5a368bb7df5cf21b0e38)
图1.5
(4)统计变量取值存在缺失值的数量。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-1.jpg?sign=1739425800-SN8FaJykWnlQzZB4ETiDPRqShKyIx1aV-0-8f1487087058850666d93923ed6ca000)
(5)计算变量取值不包括缺失值的数量。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-2.jpg?sign=1739425800-DVIO4DFzzfa5rxYNTSFkomV6ICsQBmJe-0-6c2ea46af503662a8f79c48c4ec5f736)
(6)变量Miles_per_Gallon和变量Horsepower存在缺失值。查看变量Horsepower存在缺失值,并且变量Origin取值是"Europe"的记录。输出结果如图1.6所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-1.jpg?sign=1739425800-pyhGvkkQ8xFfBOaFrJvI65vCqZvlemJ0-0-958fbf5ced16dcd90ef09aaba4dc469d)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-01.jpg?sign=1739425800-pgoKOEHeLkEfYltMxG7tLayFfZA3lZ05-0-25afa2598954c460b82b4dc0f036fc03)
图1.6
(7)使用API函数dropna()剔除包含缺失值的数据记录。这里以前20行数据记录为例,行索引出现间断情形,表明存在缺失值的数据记录已经被剔除,输出结果如图1.7所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-2.jpg?sign=1739425800-FqhSOVSXjYMtCjoHB5h2KoBHiDmBeUev-0-3458dfb720010b315864edfb135efcaf)
(8)分析剔除包含缺失值的数据记录的数量变化。从属性shape的取值来看,二元元组的行数减少,变量个数没有变化。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-3.jpg?sign=1739425800-HRhK8FhA3r0oPcPp50x1oltM7qMKrDzJ-0-824edeb3164b47244266d8dfc02f1416)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/035-01.jpg?sign=1739425800-jf0b45FmaNh3CsSTJya5bCdsXMekyFrQ-0-63a1f9a101cbdc15ef87e13e0883f1c9)
图1.7
2. 处理缺失值
使用API函数fillna()填补存在缺失值的变量或数据记录。函数fillna()的参数既可以是数值,也可以是字典。
(1)使用数值0填补存在缺失值的数据记录。这里以前20行数据记录为例,使用数值0填补存在缺失值的数据记录,行索引连续有序,输出结果如图1.8所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/035-1.jpg?sign=1739425800-kyDk7mtZgczQcNaJ5WoSsOmK9wSvAmck-0-fbad7f003d365ffa0167027e1b8d52fa)
(2)使用变量Miles_per_Gallon的均值填补存在缺失值的变量Miles_per_Gallon。输出结果如图1.9所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/035-2.jpg?sign=1739425800-5zIcCoPgIOXxqpmy6MU0riJFIZmIXQIB-0-7f2d07ced1f640d5419f4ae0e9e28e24)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/036-01.jpg?sign=1739425800-BUPIkVSQ9EteTqXO5WvbSNysPJ8bMpmc-0-228e7171bee5427a7d206af8833b6b49)
图1.8
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/036-02.jpg?sign=1739425800-vSV9po3JlCyp0db4IwIbxhwUqxW3vDg6-0-8b7bf626c855438a24ea4658912b84a5)
图1.9
(3)在填补存在缺失值的变量Miles_per_Gallon之后,比较变量取值存在缺失值的数量变化。经过比较,只有变量Horsepower存在缺失值。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-1.jpg?sign=1739425800-lXkSMn9jgPUJwTdJmsjMu4n08bFd5q6j-0-b0aed1b52bde239494a533aebff7c93d)
(4)在填补存在缺失值的变量Miles_per_Gallon之后,比较变量取值不包括缺失值的数量记录的变化。经过比较,只有变量Horsepower存在缺失值。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-2.jpg?sign=1739425800-2r1kqRHe12FjVqq4kpgr3l2WiaXBaWkj-0-d10babde6753a0d62b33f9e0381157b0)
(5)分别使用均值和最大值填补变量Miles_per_Gallon和Horsepower。不同变量的数据记录数量相同,所有缺失值都填补完成。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-3.jpg?sign=1739425800-UoiUQvl6ZeS6SifG7trtkKdKt2N8ZWvD-0-49cb4126635c6280be4f93a30cddd827)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-1.jpg?sign=1739425800-rkp9Z5mKgHPpC0NsIAFm0lHGSSHX2H3U-0-2753d1914cc8d26115ee78fdcf73cda7)
(6)使用API函数describe()展示数量型变量的描述统计。输出结果如图1.10所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-2.jpg?sign=1739425800-NNjYrJXvg3GRcKk2ifEeLGCFDStkCOmy-0-03d549e27d6103fe6ee8b12291910102)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-01.jpg?sign=1739425800-XvVw86FyypsItElCWuB4AqVCNIDWekjX-0-2c2f972a9f2bae7acb025c3e12f1ce56)
图1.10
1.5.4 条件查询的操作方法
对DataFrame而言,条件查询可以使用Pandas。条件查询类似MySQL中的where子句,使用条件表达式获得布尔值进而筛选部分数据集或变量。为了更好地演示使用方法,下面使用数据集cars的前30行数据记录作为示例数据集。实现代码如下所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-3.jpg?sign=1739425800-GVB8jv8exxABV19Xg9kBRS93NFE1qMn5-0-f74ad373ea38fa726aaa61801b437ab4)
查询条件的设置方法,以变量类型划分,主要分为数量型变量、名义型变量和时间型变量。
数量型变量的条件表达式主要使用逻辑运算符“==”、“>=”、“<=”和“!=”等,例如,source.Miles_per_Gallon==14,可以称为精确查询。名义型变量的条件表达式主要使用API函数str.contains()设置查询字符串,例如,source["Origin"].str.contains("Euro"),包含查询字符串的数据记录都会以查询结果的形式返回,可以称为模糊查询。如果使用完整的变量取值,则等价于使用逻辑运算符“==”设置条件表达式,例如,source.Origin=="Europe",属于精确查询。时间型变量的条件表达式主要使用类pandas.Timestamp()设置查询时间戳(日期和时间),例如,source2.Year==pd.Timestamp("1982"),属于精确查询。
(1)查询变量Origin的取值等于"Europe"的数据记录。条件表达式既可以使用source.Origin=="Europe",也可以使用source["Origin"]=="Europe"。条件表达式的返回值是对象Series。条件查询结果如图1.11所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-1.jpg?sign=1739425800-H676twMsIdruAJQI762AkFFfKvMmmZu4-0-e39f052922e8f3b3673eba7a5f1278b7)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-01.jpg?sign=1739425800-aiIVHKmeAMOWju8NLFmXjJGa81BEWT4T-0-f4cb18e97eea2c8b0f4b1f33eb0fcee6)
图1.11
(2)查询变量Origin的取值等于“Europe”,且变量Miles_per_Gallon的取值大于或等于15的数据记录。两个条件表达式都需要使用“()”,逻辑连接词且使用“&”,逻辑连接词“或”使用“|”。条件查询结果如图1.12所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-2.jpg?sign=1739425800-AktKc7JpyM0I0RAxiyyBxXJsaVWoOkiD-0-bcad29f043cdb7713bff7931fe310e53)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-02.jpg?sign=1739425800-AweQLzx2OqOECaoBGE3cdM38bwAVKabS-0-f0038515256ee8eb2cfa517e3a36aea5)
图1.12
(3)查询变量Origin的取值等于“Europe”或变量Miles_per_Gallon的取值等于14的数据记录。条件查询结果如图1.13所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-3.jpg?sign=1739425800-nMEsr57wDWwT2WJ4Q5B2jwz8moMToV5a-0-5dcc9ecf8eab0bb7fb8cff66818299eb)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-01.jpg?sign=1739425800-igBK13xL0l3ujGIVElEpRsxhEg2P4P5j-0-a31c432e2b00c7357b9edb4728ff3004)
图1.13
(4)查询变量Origin的取值等于“Europe”或变量Miles_per_Gallon的取值等于14的数据记录。同时,返回的数据记录只显示依次包含变量Name、Miles_per_Gallon和Origin的数据记录。可以根据显示需求调整这些变量在列表中的顺序。条件查询结果如图1.14所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-1.jpg?sign=1739425800-i67oBaEQ0iBAnQrRizfZ4ggTypfbnrL3-0-b388708730e5a097098bb05582891a89)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-02.jpg?sign=1739425800-qgeakvvTXEhCXsXnjPHrqWEjPtozzgGZ-0-40f8580e42af30f71bdce1c86d1bff93)
图1.14
(5)查询变量Miles_per_Gallon的取值大于或等于18,且变量Miles_per_Gallon的取值小于或等于25的数据记录。条件查询结果如图1.15所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-2.jpg?sign=1739425800-S5ukLdIOBPYdSens7ra8eMZrDPz2WW7F-0-0eef141779b5a67c93959acfe8c0fe3e)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-01.jpg?sign=1739425800-ur3yUHd8GsdmkHndtxrg6W0GyTLRdDkq-0-97b568da878a045251dd4c9229c4b07d)
图1.15
(6)查询变量Origin的取值包含“Euro”的数据记录。对名义型变量而言,可以使用API函数str.contains()设置查询条件,判断字符串模式或正则表达式是否匹配名义型变量的取值,返回布尔型对象Series。名义型变量Origin的条件查询结果如图1.16所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-1.jpg?sign=1739425800-MGIWDVg9W3U4YOFb35xGhfNCjsvgAtMO-0-54496ddc6f049d34d0e117239d424512)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-02.jpg?sign=1739425800-h8okYxAr3HMKPyMyFEc6XwjzFdLksNPD-0-8a1e6b90e15975fb8c752211c9dd86f1)
图1.16
(7)查询变量Name的取值包含“for”的数据记录。同时,查询结果的数据记录只包含部分变量。名义型变量Name的条件查询结果如图1.17所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-2.jpg?sign=1739425800-cWGVBDblJFs8ymbq386MT0qRYZE9B3sn-0-533138d081cd60ec80ae7b67b2883f1c)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-03.jpg?sign=1739425800-qN5GxEp5ovDieB41Y5yXm455NHCKOyej-0-9540ebc5b57f43f41cad4f634fd92981)
图1.17
(8)查询变量Name的取值包含“(”的数据记录。按照正则表达式查询,需要使用"\("。名义型变量Name的条件查询结果如图1.18所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-1.jpg?sign=1739425800-YGxILYyg3BuPdyxt57VvLAn8QUwn7LbN-0-6820752afaa869d30f46d8f0e6438a69)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-01.jpg?sign=1739425800-hcJCAcHpFnoxlgtKIOkEzTaoGJs3CZTA-0-f09c7c8f3e13330b15bea9678b3698f1)
图1.18
(9)查询变量Name的取值包含“(”的数据记录。按照字符串查询,需要传递False给关键字参数regex。同时,查询结果的数据记录只包含部分变量。名义型变量Name的条件查询结果如图1.19所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-2.jpg?sign=1739425800-sjQFwzYIRfSrAdtmcy2bCsPYkFaD0l9Y-0-25fd2dade8511d442342f19c1fc16c3a)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-02.jpg?sign=1739425800-lZ8AYb7Hq8mee86fctcwwqKyKOgszFzo-0-dad15792cab5d8c183663a8c2eae9172)
图1.19
(10)查询变量Year的取值等于1970年的数据记录。对时间型变量而言,可以使用类pandas.Timestamp()设置查询日期和时间。使用完整数据集cars作为查询范围,同时,查询结果的数据记录只包含部分变量。时间型变量Year的条件查询结果如图1.20所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-3.jpg?sign=1739425800-0b3KDbDXqKwxhQTYgg2coTByhwzqe0VI-0-70ed0c8240a9964913cc92e266431e77)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/043-01.jpg?sign=1739425800-ko8FwBCMho5GBJXxs0dALk9swDNvFJFr-0-31ce79d43f13a5e2180501a3ba8942fa)
图1.20