![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=1739528488-5yGXtA1c82Jwp1qgQnXoWwTwHYimCh1j-0-b0a0ba0a527a23dd9010aae76b29ccc2)
(2)定义一个变量,用来存储字典。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/028-2.jpg?sign=1739528488-5bkLHs3XvBfKcDYUiu8hrfT8deBYfKaO-0-af1515ca2fecdd1aeffaead01bad7675)
(3)生成Pandas中的DataFrame。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/028-3.jpg?sign=1739528488-jQB42EXCsuUaRm1cFSUxpONIsHCAGBwZ-0-83773d6365806d8098a68bf5377aa336)
如果需要查看某些变量的取值情况,则可以给DataFrame增加列索引;如果需要查看某些案例(cases),也称为观测记录(observations),即样本(samples),还可以增加行索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-2.jpg?sign=1739528488-hmJawv7lnxmP2pMHwjShEXEaBUS8dI2d-0-6d263e28c298a4244e2e5c2d8e59b9fa)
注意:输出结果中的第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=1739528488-n4jsEyyCZ3sESLgfunaYlDiLOi7jR5zl-0-4da0ac7fdf4defb352e3adb393dee2f3)
1.5.2 DataFrame的操作方法
对DataFrame而言,可以选择某一列或若干列、某一行或若干行、某一个值或若干个值,也可以查看行索引、列索引、值区域。
下面使用以下代码生成DataFrame,存储在变量df里。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-4.jpg?sign=1739528488-En6sDO5NrA8PzcftUPYn1lLKjmWIc8fm-0-6820867ca82eb7f64d71d3fe63874771)
查看行索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/029-5.jpg?sign=1739528488-e2OkM1EDNDJMSyt3bqVBq43j5S4Eu9UQ-0-ce0dc0d9f7045b2d7318dd4dc136527e)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-1.jpg?sign=1739528488-z9vL3thae1Qqs80zQbDYtscNaYwnS0nK-0-cb27f2a49d6904c9e05f2196aaf1dffd)
查看列索引。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-2.jpg?sign=1739528488-4johtGgiwYBipMjueCKQckSR8TQ7uqZH-0-7bc7bf23d2a222671068e609e7eb5d68)
查看值区域,也就是不包含行索引和列索引,这是一个二维数组,行和列的索引起始值都是0。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-3.jpg?sign=1739528488-1B4wBad16yL4TLXm9ae8nwR4x1n1RMyW-0-680c3b8d3639b8ab083f5187a88b0a70)
查看某一列和若干列。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/030-4.jpg?sign=1739528488-DDK12qWQD26eba2YSMwvCRZ23Gw7UL9r-0-79a28d88d198aee40c4ef72c39fc29e8)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-1.jpg?sign=1739528488-d4uhCUb2o8UE80q0RyOJwMhuRbSInVnp-0-bc7d6410d6fbfa5741124c5f4a967acc)
注意:选择若干列需要将列索引中的元素放在列表中,从而产生双列表。
查看某一行和若干行。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-2.jpg?sign=1739528488-hTi6WauMOoIVSH4GjLu0zylb6PWezTJT-0-8abf6deb1288ff51bcad77db1b054902)
注意:选择若干行需要将行索引中的元素放在列表里,从而产生双列表。
查看某一个值和若干个值。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/031-3.jpg?sign=1739528488-Rpsa7rG3AIDgb3rTvPQKYrJJk68vRIIR-0-34247bfc4596aab40bbf3acf7fe2adeb)
1.5.3 缺失值的操作方法
对于DataFrame而言,缺失值的识别和处理可以使用Pandas。缺失值的识别和处理是数据清理的重要环节。因此,高效、简便地识别方法和处理流程就显得尤为关键。可以从某一列或若干列、某一行或若干行、某一个值或若干个值等环节入手,高效识别缺失值。
1. 识别缺失值
使用API函数isna()或isnull()可以判断数据框(DataFrame)对象的变量取值是否存在缺失值。使用方法如下所示。
(1)导入需要的包。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-1.jpg?sign=1739528488-5Aa6xdQjD4E7Kg1M62pRPAX7i72gc6fw-0-fd31cadc6753ceef1a6574ac17539b2f)
(2)加载数据集cars。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-2.jpg?sign=1739528488-x1h2hMsXWslotkRdZ3zd0yklrwXuuslh-0-1dbf1879f19fd9573decf1932828a1ac)
(3)判断变量取值是否存在缺失值。输出结果如图1.4和图1.5所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-3.jpg?sign=1739528488-R7xbqDR99E8cWwJWB5jTnoPGjFEL81lZ-0-3bc052def4df7890d64208baf56953cf)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-01.jpg?sign=1739528488-4OmNrptYztaUCDamjnDgBPnZE5rjBAlt-0-6494bc021d7f274c9888ab68a528ca74)
图1.4
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/032-4.jpg?sign=1739528488-uzYg5oZbDqWpHcX6PFYjJncWnkHFVY78-0-a3d65f3fa16f767fcff3e02d8c343523)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-01.jpg?sign=1739528488-A2rbP81dJsl9IfYagLdiwvTNbdQ5cUtT-0-b683f9413f658ec69b8e7a118fed7aac)
图1.5
(4)统计变量取值存在缺失值的数量。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-1.jpg?sign=1739528488-w5Wcoq8o0ASumhxZQ4cBqxfknjAiR4vq-0-cf50398a22903a67e8f2e0a6c5827bd6)
(5)计算变量取值不包括缺失值的数量。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/033-2.jpg?sign=1739528488-UDO6IcfjGDu5fFFFo3pyCFEi5sBm5LpY-0-8ffe2b17e86848df5fff9478f15051d7)
(6)变量Miles_per_Gallon和变量Horsepower存在缺失值。查看变量Horsepower存在缺失值,并且变量Origin取值是"Europe"的记录。输出结果如图1.6所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-1.jpg?sign=1739528488-YWjedWcCNKUsIRljrozJYY9sccNOIObK-0-566466d461c56a00582928d6d1a0e0e9)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-01.jpg?sign=1739528488-49MswLSFXV1qYdvleb7bRIXouIFFuHRU-0-07d2cdc37f3ef449811b011a543fc796)
图1.6
(7)使用API函数dropna()剔除包含缺失值的数据记录。这里以前20行数据记录为例,行索引出现间断情形,表明存在缺失值的数据记录已经被剔除,输出结果如图1.7所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-2.jpg?sign=1739528488-eY8T6zGSI7WkNLeJH7sN7PN5FIKwQnwo-0-5cf5c309d5958f15c6491b699ed8ca1c)
(8)分析剔除包含缺失值的数据记录的数量变化。从属性shape的取值来看,二元元组的行数减少,变量个数没有变化。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/034-3.jpg?sign=1739528488-sQwdRTiE1Y8VV352AQiQS9na9z3Ygfl9-0-58280b8015a00cc2a424b95271260656)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/035-01.jpg?sign=1739528488-K4i0pNHIS2SdiqgQJ8XcKbVNCeLYlupx-0-c9b65345b4ef2f0a67798736bffa99ef)
图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=1739528488-038tBXRaWJORj97netWtmueoDZhoDpKn-0-d628c78f0a531dcd96958e60632c61ae)
(2)使用变量Miles_per_Gallon的均值填补存在缺失值的变量Miles_per_Gallon。输出结果如图1.9所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/035-2.jpg?sign=1739528488-tYC2JM8LGc3YEopOiukhbjIcsc68EqM1-0-871da99da003395fd998697f0ae1f931)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/036-01.jpg?sign=1739528488-3E5rYmKHsynjX1dFzpoAq0OW2oQAtNhs-0-777b1b8ee0645d7d53055b3ccbc07d29)
图1.8
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/036-02.jpg?sign=1739528488-FgtXjQPG1ZrK9CtAN3DDFYWQ8EDJFjFv-0-4f5f63549dfebd5644ce0d5c37d526cb)
图1.9
(3)在填补存在缺失值的变量Miles_per_Gallon之后,比较变量取值存在缺失值的数量变化。经过比较,只有变量Horsepower存在缺失值。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-1.jpg?sign=1739528488-PtNF3n81NPSDfMjJvSBmbrVJvLE1RFbF-0-c3d656c1acc994b5adb42df227a2ec65)
(4)在填补存在缺失值的变量Miles_per_Gallon之后,比较变量取值不包括缺失值的数量记录的变化。经过比较,只有变量Horsepower存在缺失值。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-2.jpg?sign=1739528488-zdIqI3rC1czP5ILsAqfk8SjWILVOc8kO-0-531822f1c1832355436e21a0ead9636e)
(5)分别使用均值和最大值填补变量Miles_per_Gallon和Horsepower。不同变量的数据记录数量相同,所有缺失值都填补完成。输出结果如下。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/037-3.jpg?sign=1739528488-xZvxIF5W5GgXD7sNS7dInWWkHbDgzwjT-0-49b9146800ffeac0038ca20fd80c460a)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-1.jpg?sign=1739528488-ja5FIB15tTjP7LOmdTyMGiir8EjQsjvd-0-7941c8202e7eadde7c4a97da93a1b557)
(6)使用API函数describe()展示数量型变量的描述统计。输出结果如图1.10所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-2.jpg?sign=1739528488-gLl2BnKMYzR6JaLBzpIxhfZUlKqp4VRr-0-1b73183e900c148f31ebc6439c3ce88a)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-01.jpg?sign=1739528488-HlwA9xNYPevUtMbLkZEOneVupxzszZHa-0-ca66ff249e402750702f2cee796138fc)
图1.10
1.5.4 条件查询的操作方法
对DataFrame而言,条件查询可以使用Pandas。条件查询类似MySQL中的where子句,使用条件表达式获得布尔值进而筛选部分数据集或变量。为了更好地演示使用方法,下面使用数据集cars的前30行数据记录作为示例数据集。实现代码如下所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/038-3.jpg?sign=1739528488-aM86ILebToTG8HNK212o668AmQYgeHIS-0-3f6051895894f54a0bdc7c8a2bc9542e)
查询条件的设置方法,以变量类型划分,主要分为数量型变量、名义型变量和时间型变量。
数量型变量的条件表达式主要使用逻辑运算符“==”、“>=”、“<=”和“!=”等,例如,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=1739528488-s6shYxGoFCV8qYMvoWnHFBLfFXb7nHAK-0-848ac0fe2438e18210add173fd518685)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-01.jpg?sign=1739528488-l6hO13Wja8NFCeC6OOrfJJQWQjrG9hZf-0-e9c94b4fc4501722aa2be161d3d971a3)
图1.11
(2)查询变量Origin的取值等于“Europe”,且变量Miles_per_Gallon的取值大于或等于15的数据记录。两个条件表达式都需要使用“()”,逻辑连接词且使用“&”,逻辑连接词“或”使用“|”。条件查询结果如图1.12所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-2.jpg?sign=1739528488-YHpC7yIKSQQ16Q6DwsRCUHt91mNbRKls-0-46cf7575b8f5300e4c06c632cce22c3c)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-02.jpg?sign=1739528488-pP8Q9D8oT9klF8sozb9djMTQVklN77uD-0-ffce9a0d9187d2fa957d7dde8da74f21)
图1.12
(3)查询变量Origin的取值等于“Europe”或变量Miles_per_Gallon的取值等于14的数据记录。条件查询结果如图1.13所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/039-3.jpg?sign=1739528488-cDDaUlcuaJ1bSrbRb7vr5PfypB21KydG-0-7c77fdd617ff012e541aafbb861c3b5c)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-01.jpg?sign=1739528488-VBUJ87dln5DMpxfIiqDL5F0ERHB3ehcb-0-72b80589dfcc6487c62d4e258e00666d)
图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=1739528488-u37y63to56FA62W3BUcqF4RFUMc877Qn-0-f9faac4c0b3445b64704e0c4f2ff6370)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/040-02.jpg?sign=1739528488-rGbed1ZadgAtMPU0NoOmsG5LHJ31EbBF-0-36ff9207998d7e7315d6ce01e924bc98)
图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=1739528488-GHvSpdvYzRovc6iriMKu0j4QMZf1kVmg-0-597a1610c14b065900e39d39a1d2f95a)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-01.jpg?sign=1739528488-C37ebm7GrX45eZtb8HWk5VaJMaZ0LpjR-0-7df58eaa7ede59d5029088965805b654)
图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=1739528488-c4cTXnOMpQiO8x2RASf6osAxehy3z9As-0-04081da49ffcd11dcf4fdfad155ba5c8)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-02.jpg?sign=1739528488-MiRPNtNLZiELbxYwu1hZx4MLewRbJ9eh-0-d3a6a79cb9f6dc507fbdb715d30ff371)
图1.16
(7)查询变量Name的取值包含“for”的数据记录。同时,查询结果的数据记录只包含部分变量。名义型变量Name的条件查询结果如图1.17所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-2.jpg?sign=1739528488-o6eZTsEJqpULC5UHWxrzlHE4ojy4E5Uz-0-de20d26575d4a7e29253d331df67fbf5)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/041-03.jpg?sign=1739528488-xcXTUOLuogVimOuZLb3yztBvXNMoyFrp-0-650c5a985a5240e8ac1700e88546a188)
图1.17
(8)查询变量Name的取值包含“(”的数据记录。按照正则表达式查询,需要使用"\("。名义型变量Name的条件查询结果如图1.18所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-1.jpg?sign=1739528488-vKPBlnZ5owBRoaDyDLypn0zlyVtBdxtk-0-a6f7c9035e495af7f5ec5d354f7107b5)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-01.jpg?sign=1739528488-9ezvZqT4G2xvRTORfSABZ7JW4dTcLQwO-0-55317e20a74327aeafbc9c031c0dffaa)
图1.18
(9)查询变量Name的取值包含“(”的数据记录。按照字符串查询,需要传递False给关键字参数regex。同时,查询结果的数据记录只包含部分变量。名义型变量Name的条件查询结果如图1.19所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-2.jpg?sign=1739528488-x203Clo04VXLZEslNEV2McvyLjpXidnM-0-adc287c526b0368ef2ae073e362a7c67)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-02.jpg?sign=1739528488-UZkunyl0b3kl6h1RUm60XicfYxawct7a-0-a9ca874e88b0312bcb7ca6f994f7f186)
图1.19
(10)查询变量Year的取值等于1970年的数据记录。对时间型变量而言,可以使用类pandas.Timestamp()设置查询日期和时间。使用完整数据集cars作为查询范围,同时,查询结果的数据记录只包含部分变量。时间型变量Year的条件查询结果如图1.20所示。
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/042-3.jpg?sign=1739528488-mBJ1QkHcwC27kdiPEkb2VYSlMeAFo24c-0-4203486cb347cdf881667e46073c912b)
![](https://epubservercos.yuewen.com/A9DFFD/23020653609770806/epubprivate/OEBPS/Images/043-01.jpg?sign=1739528488-DkrTQ7odoZJn1NAtllDweeuj27ORQhkH-0-752d1eb9ab094149ff95e09912d8f01c)
图1.20