![Python数据可视化之美:专业图表绘制指南(全彩)](https://wfqqreader-1252317822.image.myqcloud.com/cover/380/31186380/b_31186380.jpg)
2.2 Pandas:表格处理
Pandas提供了3种数据类型,分别是Series、DataFrame和Panel。其中,Series用于保存一维数据,DataFrame用于保存二维数据,Panel用于保存三维或者可变维数据,其提供的数据结构使得Python做数据处理变得非常快速与简单。平常的数据分析最常用的数据类型为Series和DataFrame,而Panel较少用到。在Python中调用Pandas往往使用如下约定俗成的方式:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_32_2.jpg?sign=1739273019-goExRGCzEznbRmcGZ4CTdm4H4F5elx9A-0-0bcea436ceb7f3e106b2a94e1c02ff30)
2.2.1 Series数据结构
Series本质上是一个含有索引的一维数组,看起来,其包含一个左侧可以自动生成(也可以手动指定)的index和右侧的values值,分别使用s.index s.values进行查看。index返回一个index对象,而values则返回一个array(见表2-2-1)。
Series就是一个带有索引的列表,为什么我们不使用字典呢?一个优势是,Series更快,其内部是向量化运行的,和迭代相比,使用Series可以获得显著的性能上的优势。
表2-2-1 Series的创建与属性
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_32_3.jpg?sign=1739273019-2MEzM1FBy4UzSksnR3YjJLNIa7Xrr4lf-0-6a02fc3f5e7eaac2b270cb1a25e18af4)
2.2.2 数据结构:DataFrame
DataFrame(数据框)类似于Excel电子表格,也与R语言中DataFrame的数据结构类似。创建类DataFrame实例对象的方式有很多,包括如下几种(见表2-2-2)。
● 使用list或者ndarray对象创建DataFrame:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_33_1.jpg?sign=1739273019-HgWBJ7lZ5DxDHT4sGaKQdUF0hxbKAy26-0-e33ebf0c8a7164da5c0e7c481d489d47)
● 使用字典创建DataFrame:使用字典创建DataFrame实例时,利用DataFrame可以将字典的键直接设置为列索引,并且指定一个列表作为字典的值,字典的值便成为该列索引下所有的元素。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_33_2.jpg?sign=1739273019-pyrTLJZBfzuTFBgzhLbDIAXhrnektGrG-0-587e7e1bc07f536ecb344803ed9c207e)
需要注意的是:数据框的行索引默认是从0开始的。
表2-2-2 数据框数据的选取
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_33_3.jpg?sign=1739273019-KUxS7gCmAMnSbODVzEF4i1ChZqeeiaCV-0-2360364c7d190faee1bbc0e5608bb5ae)
● 获取数据框的行数、列数和维数:df.shape[0]或len(df)、df.shape[1]、df.shape。
● 获取数据框的列名或行名:df.columns、df.index。
■ 重新定义列名:df.columns=["X","Y","Z"]。
■ 重新更改某列的列名:df.rename(columns={'x':'X'},inplace=True)。注意,如果缺少inplace选项,则不会更改,而是增加新列。
● 观察数据框的内容。
■df.info():info属性表示打印DataFrame的属性信息。
■df.head():查看DataFrame前五行的数据信息。
■df.tail():查看DataFrame最后五行的数据信息。
数据框的多重索引:通常DataFrame(数据框)只有一列索引,但是有时候要用到多重索引。表2-2-3中的df.set_index(['X','year'])就有两层索引,第0级索引为“X”,第1级索引为“year”,这时使用loc方法选择数据。
表2-2-3 数据框的多重索引
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_34_1.jpg?sign=1739273019-Pso6S8S7dafPWjM7HMlon8cOf0W81F6j-0-0fe7af6ee5372eceb30d6b79d09eeff1)
空数据框的创建:空数据框的创建在需要自己构造绘图的数据框数据信息时,尤为重要。有时候,在绘制复杂的数据图表时,我们需要对现有的数据进行插值、拟合等处理时,再使用空的数据框存储新的数据,最后使用新的数据框绘制图表。创建空数据框的方法很简单:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_34_2.jpg?sign=1739273019-fX5gFhbQDTMWhQ08IGUqCGWJqGAfbhX1-0-46969085be2762d1d5e8337657a0c7c1)
网格分布型数据的创建:在三维插值展示时尤为重要。结合np.meshgrid()函数可以创建网格分布型数据框,如下所示。np.meshgrid()函数就是用两个坐标轴上的点在平面上画网格(当传入的参数是两个的时候)。也可以指定多个参数,比如3个参数,那么就可以用三个一维的坐标轴上的点在三维平面上画网格(见表2-2-4)。
表2-2-4 网格分布型数据的创建
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_35_1.jpg?sign=1739273019-NvWMblq5m41v7zElQQn2fGmlWudgiocm-0-10305e55b70acf5ad1f7d0d82fd99b97)
2.2.3 数据类型:Categorical
Pandas拥有特殊的数据结构类型:Categorical(分类)可以用于承载基于整数的类别展示或编码的数据,可分为类别型和有序型,类似于R语言里面的因子向量(factor)。分类数据类型可以看成是包含了额外信息的列表,这额外的信息就是不同的类别,可以称之为类别(categories)。分类数据类型在Python的plotnine包中很重要,因为它决定了数据的分析方式以及如何进行视觉呈现。
1.分类数据的创建
一个分类数据不仅包括分类变量本身,还可能包括变量不同的类别(即使它们在数据中不出现)。分类函数pd.Categorical()用下面的选项创建一个分类数据。对于字符型列表,分类数据的类别默认依字母顺序创建:[Fair,Good,Ideal,Premium,Very Good]。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_35_2.jpg?sign=1739273019-bTxTsqnsJS3MqZAOdcr624MPAcNmJOT1-0-d281dc4780e5682e49ec8789dca4262a)
很多时候,按默认的字母顺序排序的因子很少能够让人满意。因此,可以指定类别选项来覆盖默认排序。更改分类数据的类别为[Good,Fair,Very Good,Ideal,Premium],可以在使用pd.Categorical()函数创建分类数据的时候就直接设定好类别。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_35_3.jpg?sign=1739273019-ZbAVVWfx7sUndiQTPEMF4ezg8lOh23Kg-0-9c03ba351ee5be4701eb99753ef129bc)
2.类别的更改
对于已经创建的分类数据或者数据框,可以使用*.astype()函数指定类别选项来覆盖默认排序,从而将分类数据的类别更改为[Good,Fair,Very Good,Ideal,Premium]。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_1.jpg?sign=1739273019-zw4AOrOIiNgN9t9JtPp5ExDua21YvJYi-0-66f436b5688925607e6e0283dd26f8f4)
当ordered=True时,类别为有序的[Good<;Fair<;Very Good<;Ideal<;Premium]。
3.类型的转换
有时,我们需要获得分类数据的类别(categories)和编码(codes),如表2-2-5所示。这样相当于将分类型数据转换成数值型数据。
表2-2-5 因子类型的转换
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_2.jpg?sign=1739273019-KrYJ6B6wx8ZEFKkManrMRu2PeV4eoYPY-0-3f0c4e84addb21abbd6a3762b8fad90f)
如果需要从另一个数据源获得分类编码数据,则可以使用from_codes()函数构造。如下所示的Cut_Factor3输出结果为[Fair,Good,Ideal,Fair,Fair,Good],其中categories(3,object)为:[Fair,Good,Ideal]。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_3.jpg?sign=1739273019-Q4j5x4YlNRhVXSeMzLAxSfIa5rnwglxJ-0-2a42db04a022af81cd9aa59970a434bb)
2.2.4 表格的变换
使用Python的plotnine包绘图或者做分组groupby()计算处理时,通常是使用一维数据列表的数据框。但是如果导入的数据表格是二维数据列表,那我们需要使用pd.melt()函数,可以将二维数据列表的数据框转换成一维数据列表。我们首先构造数据框df:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_4.jpg?sign=1739273019-atb1W0QZWSQoISqQ0gDlmykQm6tbj79I-0-ce90924838eddd55b4c9e5f91a153351)
(1)将宽数据转换为长数据。将多行聚集成列,从而二维表变成一维表(见图2-2-1):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_1.jpg?sign=1739273019-QP02BAXoWMkqBBCGOut4A1kE9mzVPJaf-0-6a0de840cace20cde9caf00d81d4a85c)
图2-2-1 表格变换处理的示意案例
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_5.jpg?sign=1739273019-if7I13jKb5psBZEAcbkzX3cuGxN20wEA-0-c558851de5d62a40fa29426bbbf98c67)
其中,id.vars("x")表示由标识变量构成的向量,用于标识观测的变量;variable.name("year")表示用于保存原始变量名的变量的名称;value.name("value")表示用于保存原始值的名称。
(2)将长数据转换为宽数据。将一列根据变量展开为多行,从而一维表变二维表:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_6.jpg?sign=1739273019-Ku2O90gL5ZwUmskBfycGu7DTpvo5Y9nw-0-c32778990e333d6d97e3f3f048beec1b)
2.2.5 变量的变换
有时候,我们需要对数据框某列的每个元素都进行运算处理,从而产生并添加新的列。我们可以直接对数据框的某列进行加减乘除某个数值的运算,从而产生新列:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_2.jpg?sign=1739273019-CiH8EU6zfMqgyEsgOsQvxD7eQIw9mhGJ-0-5a191f98d43ff7e7770bb37e4a26b9da)
使用Python的transform()函数,结合lamdba表达式可以为原数据框添加新的列,改变原变量列的值。同时结合条件语句的三元表达式ifelse()进行更加复杂的运算(见图2-2-2):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_3.jpg?sign=1739273019-rtHe9bZjb499459gbB6HIEjBg8aMV9rK-0-c7f07daf4d7d82dfd40da014b6c7ee81)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_4.jpg?sign=1739273019-TLCO7cFkbOFphLGRdY2bM7XiwsPo8L7P-0-181d61aa100eb4bf89372544212349bf)
图2-2-2 变量变换的示意案例
apply、applymap和map方法都可以向对象中的数据传递函数,主要区别如下:
● apply的操作对象是DataFrame的某一列(axis=0)或者某一行(axis=1);
● applymap的操作对象是元素级,作用于每个DataFrame的每个数据;
● map的操作对象也是元素级,但其是对Series中的每个数据调用一次函数。
2.2.6 表格的排序
我们可以使用np.sort()函数对向量进行排序处理。对于数据框,也可以使用sort_values()函数,根据数据框的某列数值对整个表进行排序。其中,ascending=False表示根据df的value列做降序处理,如dat_arrange2数据框所示(见图2-2-3)。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_1.jpg?sign=1739273019-fd9kiFCl6VXQMrALeYsxbZz4YyC0ueEb-0-581974a8a7a8d08f9fd99cc7170721a1)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_2.jpg?sign=1739273019-Z23iTUkdMUvvaKJgyzJTxWuXDc6g2TXZ-0-5db86b673e94546c135505fa2aed1dde)
图2-2-3 表格排序的示意案例
2.2.7 表格的拼接
有时候,我们需要在已有数据框的基础上添加新的行/列,或者横向/纵向添加另外一个表格。此时我们需要使用pd.concat()函数或者append()函数实现该功能。先构造3个数据框,如下(见图2-2-4)。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_3.jpg?sign=1739273019-yt9N1rcbXqjB13esOQzCFqjoVMZyosdq-0-a4081ddc0eaa46f40d9480a76e3d7307)
(1)数据框添加列或者横向添加表格:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_4.jpg?sign=1739273019-wORnUycLSuANRkFlY6UuTYyFt7a625yf-0-950190e8789cb5cf04100d4248ef55dc)
其中axis表示沿纵轴(axis=0)或者横轴(axis=1)方向连接。(2)数据框添加行或者纵向添加表格:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_5.jpg?sign=1739273019-Ok4OK8Xk9EBsnvbQFKkx0wyXob38tZRj-0-a3014acaffc480bc9790d2db842a424f)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_6.jpg?sign=1739273019-kWSffsqxrXDLQif5e0SqAkr5ADsMUSW2-0-a443d679c766fc142c6d9821205670ff)
图2-2-4 表格拼接的示意案例
(3)可以添加行/列,也就可以删除某行/列,这时需要使用*.drop()函数.比如要删除df1的"y"列:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_7.jpg?sign=1739273019-XmSFJjfiyzb3Mq2Qgk1glWflQTfFiP13-0-16c023e26a05c0f80ad2b47bb5fd0029)
其中,labels就是要删除的行/列的名字,用列表给定;axis默认为0,指删除行,因此删除columns时要指定axis=1;index直接指定要删除的行;columns直接指定要删除的列;inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新DataFrame;inplace=True,则会直接在原数据上进行删除操作,且删除后无法返回。
2.2.8 表格的融合
有时候,两个数据框并没有很好地保持一致。若不一致,则不能简单地直接拼接。所以它们需要一个共同的列(common key)作为融合的依据。在表格的融合中,最常用的函数是pd.merge()函数。我们首先构造4个数据框如下(见图2-2-5):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_1.jpg?sign=1739273019-371h6tbjmN9WBSOoXoDY5ZUIzJB5wb5L-0-7d2c94595584d6d0cf32a10ab01a129a)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_2.jpg?sign=1739273019-ut1KktOPesxGtLziVDzKQ2lv1SdFg3b0-0-02fc2620c83d6991d248723ae0c3374e)
图2-2-5 表格融合的示意案例
通过设定pd.merge()函数的不同参数可以实现不同的表格融合效果。其中,两个表格融合会用缺失值NA代替不存在的值(见图2-2-6和图2-2-7)。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_3.jpg?sign=1739273019-vXPqLpxWjSCnVtf992S0lRZ3sG5bedEe-0-084357d1874252f5943ca51beb112dad)
图2-2-6 pd.merge()函数融合表格的示意案例
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_4.jpg?sign=1739273019-G3PYALSsfgmNIuqnw0qecd1cycoxQJGz-0-e1ae43114ce94c7eba799d8340029314)
图2-2-7 复杂的pd.merge()函数融合表格的示意案例
● 只保留左表的所有数据:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_1.jpg?sign=1739273019-9HPVU61TqMMhvD0r1nugosMZzFMjz9HN-0-8b2bb5de94c3696b551615611c61ac0d)
● 只保留右表的所有数据:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_2.jpg?sign=1739273019-3Ilg7gahkHkIjXO653YLzhMRsCBdHOY3-0-090c26ebef9aff1e7bafe3d6dbee69a1)
● 只保留两个表中公共部分的信息:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_3.jpg?sign=1739273019-Cf6Sl3p9HDzHOEK75iOJnYHO1OlWsoHN-0-8bef3d414759abd61907d00c0d2cd575)
● 保留两个表的所有信息:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_4.jpg?sign=1739273019-pnGNX6EneFmncZkxOZB0muOd6tnBMFBU-0-504f8a93e7415af93730aef7b3eb3719)
● on=["x","y"]表示多列匹配:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_5.jpg?sign=1739273019-yrwF54yUltsFiASpRYNgPToFQXoSjuZX-0-afba63de3d9ad4837ffa96f102f4aba9)
● left_on="x",right_on="g"可以根据两个表的不同列名合并:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_6.jpg?sign=1739273019-eSxpCugjB7pDsWqIPrg4eqQ0soErs6Ap-0-5eb9741f3eb7263d1fc88a977ca13f00)
● 如果在表合并的过程中,两个表有一列同名,但是值不同,合并时又都想保留下来,就可以用suffixes给每个表的重复列名增加后缀:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_7.jpg?sign=1739273019-KowrDya2nzvXa1GwsSUbee5VAh4QitI2-0-70eb99a4055d4f70f3f0dd36a76085af)
2.2.9 表格的分组操作
数据框往往存在某列包含多个类别的数据,如df.x包含A、B和C三个不同类别的数据,df_melt.year包含2010和2011两个类别的数据。我们有时需要对数据框的列或者行,亦或者按数据类别进行分类运算等,此时数据的分组操作就尤为重要。先构造两个数据框如下(见图2-2-8):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_8.jpg?sign=1739273019-1sSlq7pUXhdlyHD2uGHzem3Ab3m5q9ts-0-11b136091180329917d3a210ff759e05)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_9.jpg?sign=1739273019-zNN0V6AXpvMcbkRNLOYnjAGCZD2uuQSC-0-d47b6eb7d70d143f9cd0409767571366)
图2-2-8 对数据框按行或列求和
使用df_melt.info()函数可查看df_melt的数据信息,如图2-2-9所示。可以发现year是object数据类型,如果需要将year变成int格式,则需要:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_1.jpg?sign=1739273019-Bdrj6DdzlHF2wCvAfbQssXWvn1FwbXMq-0-a4b2181fcb94cd5586a9748078fd1a94)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_2.jpg?sign=1739273019-B2svWVP1JgXXDOUNyokw1R4mxmMyz4WB-0-73e40a4096299ac1a1f24b66e8834b30)
图2-2-9 df_melt的数据信息
1.按行或列操作
● 按行求和:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_3.jpg?sign=1739273019-44f9OWfwgTzDt5B7WqPcOxNubkIpjRp6-0-73658f37ac00d1d31763b7428f9c5494)
● 按列求和:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_4.jpg?sign=1739273019-AZqM0rKFabsv64By91vzFlmeNr3eJVu4-0-86266117dd84acf6b7acfcb93d81741f)
● 单列运算:在Pandas中,DataFrame的一列就是一个Series,可以通过map或者apply函数来对某一列进行操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_5.jpg?sign=1739273019-UMqSLjMY2RrSVcVseOrDes6nzSMF7jZV-0-cea66c24786b9ac69024a1963f01c34a)
● 多列运算:要对DataFrame的多个列同时进行运算,可以使用apply()函数。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_6.jpg?sign=1739273019-cquLzOmk0MTqus1cFqDBVeJFGcOkdEYZ-0-5c3c9776ebb8ec7e01a8435d06da3b05)
2.分组操作:groupby()函数
● 按year分组求均值,如图2-2-10所示:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_7.jpg?sign=1739273019-QTfNzPuIQBhLMlecoZQ57q2vyjGpKKFs-0-060039af68e135a465605d7612b5215b)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_8.jpg?sign=1739273019-BwD5o6BbJ9EMTwC6jdyCBAouGUkrN4xC-0-e493b2dfc56277fce5d4414ccf6332fe)
图2-2-10 按year分组求均值
● 按year和x两列变量分组求均值,如图2-2-11所示:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_1.jpg?sign=1739273019-1NlVzf2XABgke4yel2ceTVb2wx3vW7wy-0-40f085a49522d8433d30f53600c3e122)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_4.jpg?sign=1739273019-GjB3U1SyQMDA4X55Pwx4fkRo1qS0ZzyA-0-42acd60a525f51c4ccb169ba0243b03b)
图2-2-11 按year和x两列变量分组求均值
其中,as_index=False不会将['year','x']两列设定为索引列。
● 按year分组求和:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_2.jpg?sign=1739273019-714rE9HkqQqcixuTsA9np7W3SbhNmkvo-0-483733f52d866f83d976f8dbd3cfcc6d)
● 按year分组求方差:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_3.jpg?sign=1739273019-iOg0a0qDZ00rRVjh6HTnBPWHjJouRlON-0-151fdf34068e0491610cd91c97af46d8)
3.分组聚合:aggregate()函数
aggregate()函数结合groupby()函数可以实现SQL中的分组聚合运算,如图2-2-12所示。aggregate()函数也可以简写为agg()。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_5.jpg?sign=1739273019-yhUjuqERowTTsz2C3o6aBhjxXr03ImWF-0-4fbda3f42253506c83affcadd9c43b59)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_6.jpg?sign=1739273019-udAaai8gK7IfWzpWXKR5Cbb6Kdhiatj5-0-9a36d8bc07d2be9326abcedb2192fd23)
图2-2-12 aggregate分组聚结果
4.分组运算:transform()函数
transform()函数可以结合groupby来方便地实现类似SQL中的分组运算的操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_1.jpg?sign=1739273019-Jv4P9lKWpCXUSIfMqu41h0DoztZIgDd6-0-77ce3197a5216f2ec2fce3f762aa9d5a)
5.分组筛选:filter()函数
filter()函数可以结合groupby来方便地实现类似SQL中的分组筛选运算的操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_2.jpg?sign=1739273019-kHhYs3rkJe9H3mNdLkwLjivYNnzH3sfs-0-aa89afa08e2023f1cc7be89320ec12d3)
2.2.10 数据的导入与导出
大部分时候我们都是直接导入外部保存的数据文件,再使用它来绘制图表。此时,就需要借助数据导入函数导入不同格式的数据,包括CSV、TXT、Excel、SQL、HTML等格式的文件。有时,我们也需要将处理好的数据从Python中导出保存。其中,我们在数据可视化中使用最多的就是前3种格式的数据文件。
(1)CSV格式数据的导入与导出
使用pd.read_csv()函数,可以读入CSV格式的数据,并以DataFrame形式存储。根据所读取的数据文件编码格式设置encoding参数,如utf8、ansi和gbk等编码方式,当导入的数据存在中文字符时,要尤为注意。根据所读取的数据文件列之间的分隔方式设定delimiter参数,大于一个字符的分隔符被看作正则表达式,如一个或者多个空格(\s+)、tab符号(\t)等。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_3.jpg?sign=1739273019-WXMDV86LlFeUDQT5hoRMCUQ8k2GAQJBV-0-9a4cb81d177ba3783d6290405a5c17aa)
使用to_csv()函数,可以将DataFrame的数据存储为CSV文件:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_4.jpg?sign=1739273019-RBJUtT8mNF1KLSnKQhr7WaeFWEMhtcHe-0-e312b06ae85db62aea763a30b43ac144)
index=False,表示忽略索引信息;index=True,表示输出文件的第一列保留索引值。
CSV文件的特点主要有以下几个:①文件结构简单,基本上和TXT文本文件的差别不大;②可以和Excel进行转换,这是一个很大的优点,很容易进行查看模式转换,但是其文件存储大小比Excel小。③简单的存储方式,可以减少存储信息的容量,有利于网络传输及客户端的再处理;同时由于是一堆没有任何说明的数据,具备基本的安全性。相比TXT和Excel数据文件,笔者推荐使用CSV格式的数据文件,进行导入与导出操作。
(2)TXT格式数据的导入与导出
如果将电子表格存储在TXT文件中,可以使用np.loadtxt()函数加载数据。需要注意的是:TXT文本文件中的每一行必须含有相同数量的数据。使用np.loadtxt()函数可以读取数据并存储为ndarray数组,再使用pd.DataFrame()函数可以转换为DataFrame格式的数据。其中,np.loadtxt()函数中的参数delimiter表示分隔符,默认为空格。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_1.jpg?sign=1739273019-EJADsnZDUF8FWHyoQVbPDPkAMR4PMxEZ-0-97d099f4a4ac0bf31877191a42ff229e)
使用numpy.savetxt(fname,X)函数可以将ndarray数组保存为TXT格式的文件,其中参数fname为文件名,参数X为需要保存的数组(一维或者二维)。
(3)Excel格式数据的导入与导出
我们可以使用pd.read_excel()和to_excel()函数分别读取与导出Excel格式的数据:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_2.jpg?sign=1739273019-nHggG5F60HnaHCr7QKnWYM33RNoyRyLo-0-5305a11fe38ea804ae60fd1b1031820d)
其中,sheetname指定页面sheet,默认为0;header指定列名行,默认为0,即取第一行,数据为列名行以下的数据;若数据不含列名,则设定header=None。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_3.jpg?sign=1739273019-lHKJAhFeusvjD6k8VpIpBZxcKz2QgYdV-0-c5058478966c6a95acc489d9f2fd7c59)
其中,excel_writer表示目标路径;index=False表示忽略索引列。
需要注意的是:使用plotnine包绘制图表或者pandas包处理数据时,通常使用一维数据列表的数据框。但是如果导入的数据表格是二维数据列表,那么我们需要使用pd.melt()函数,可以将二维数据列表的数据框转换成一维数据列表。
一维数据列表和二维数据列表的区别
一维数据列表就是由字段和记录组成的表格。一般来说字段在首行,下面每一行是一条记录。一维数据列表通常可以作为数据分析的数据源,每一行代表完整的一条数据记录,所以可以很方便地进行数据的录入、更新、查询、匹配等,如图2-2-13所示。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_4.jpg?sign=1739273019-oGtgDwsP2hAfyMRMXMNdKQ4oZUiO5Gsn-0-7a952a6829f2a57b180290d6aab59d5a)
图2-2-13 一维数据列表
二维数据列表就是行和列都有字段,它们相交的位置是数值的表格。这类表格一般是由分类汇总得来的,既有分类,又有汇总,所以是通过一维数据列表加工处理过的,通常用于呈现展示,如图2-2-14所示。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_5.jpg?sign=1739273019-ToytaeGrTRyOEnVUNGWhnkkYAosjWgk7-0-f0e622791f1d896c62cc28be5d4377d5)
图2-2-14 二维数据列表
一维数据列表也常被称为流水线表格,它和二维数据列表做出的数据透视表最大的区别在于“行总计”。判断数据是一维数据列表还是二维数据列表的一个最简单的办法,就是看其列的内容:每一列是否是一个独立的参数。如果每一列都是独立的参数,那就是一维数据列表;如果每一列都是同类参数,那就是二维数据列表。
注意,为了后期更好地创建各种类型的数据透视表,建议用户在录入数据时,采用一维数据列表的形式,避免采用二维数据列表的形式。
2.2.11 缺失值的处理
导入的数据有时存在缺失值。另外,在统计与计算中,缺失值也不可避免,也起着至关重要的作用。Python使用np.nan表示缺失值。Pandas包也提供了诸多处理缺失值的函数与方法(见表2-2-6)。
表2-2-6 缺失值的处理
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_45_1.jpg?sign=1739273019-I8LxCarMVILx6ureceLCpkI06AMTnf74-0-b9fa55a2b7e9ac05285d1dad25d4b34e)