![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=1739544609-mNGfp35bgw0ufdZSOsgiOPKmJOBctN3s-0-53a3f8f917fdccecd07ff0d8d36df1d3)
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=1739544609-dmWZ7rsFZl1fE5MQpF9PorIRuvIMSDPJ-0-af3dfcee40a7f5a151ff671657561c03)
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=1739544609-Dv6v6GoJHVwvoWcpVFnXE1c8irJyCqN9-0-8bff093c0fdb095524c3967ed52eaba1)
● 使用字典创建DataFrame:使用字典创建DataFrame实例时,利用DataFrame可以将字典的键直接设置为列索引,并且指定一个列表作为字典的值,字典的值便成为该列索引下所有的元素。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_33_2.jpg?sign=1739544609-1KzyENb3sYw8oNKfb4jaP8qXp00O0Ixd-0-14359f9b47ddb0ea0fde87094c40f9ae)
需要注意的是:数据框的行索引默认是从0开始的。
表2-2-2 数据框数据的选取
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_33_3.jpg?sign=1739544609-CnUl9CPcPpj24Xkb9bmMJUvGP3ZMnLRm-0-acbe04379cd751c8e60f65f42d3adb0c)
● 获取数据框的行数、列数和维数: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=1739544609-xk7jJeaeybR7OzbkrJxa5U0KXuOZoW26-0-4b470650f64192f471aebc7d36fb0258)
空数据框的创建:空数据框的创建在需要自己构造绘图的数据框数据信息时,尤为重要。有时候,在绘制复杂的数据图表时,我们需要对现有的数据进行插值、拟合等处理时,再使用空的数据框存储新的数据,最后使用新的数据框绘制图表。创建空数据框的方法很简单:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_34_2.jpg?sign=1739544609-DqcLtCEk4YqOOhv3gxWAZg5PrtJqcOAE-0-4138fa8be2b64b4d0f2659f66b441bfd)
网格分布型数据的创建:在三维插值展示时尤为重要。结合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=1739544609-gErcJwJ57ymkjtjUdsVqVOjhVHSjwE26-0-6aea5d4accd36d59bb8ac3507b80ed67)
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=1739544609-QDkBPgUUnCfaiHiQQLwGRl4O9kWFL7MY-0-e6114c4f9238d1f85751d5b349afc58a)
很多时候,按默认的字母顺序排序的因子很少能够让人满意。因此,可以指定类别选项来覆盖默认排序。更改分类数据的类别为[Good,Fair,Very Good,Ideal,Premium],可以在使用pd.Categorical()函数创建分类数据的时候就直接设定好类别。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_35_3.jpg?sign=1739544609-2Icm9IJ6Q08urPBZeM2VKQ73ife09ly6-0-d392eace2b5ee8cd8e60675759f029fd)
2.类别的更改
对于已经创建的分类数据或者数据框,可以使用*.astype()函数指定类别选项来覆盖默认排序,从而将分类数据的类别更改为[Good,Fair,Very Good,Ideal,Premium]。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_1.jpg?sign=1739544609-5d6LgOwA0z7ky9bNj6PXtWg1fgEbRZgs-0-492824b2880a64b5a6f9e73b0db5255e)
当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=1739544609-emK7mAdTcDqApDfNq5WlTHYEgbeHykDq-0-53b2c44d83d746e5d0139e3624720b08)
如果需要从另一个数据源获得分类编码数据,则可以使用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=1739544609-9LaOouvVC2ZmVWnZgMzeu50Mv9hkYDFl-0-d57bcd8c0bf732245611c109a5d7f32c)
2.2.4 表格的变换
使用Python的plotnine包绘图或者做分组groupby()计算处理时,通常是使用一维数据列表的数据框。但是如果导入的数据表格是二维数据列表,那我们需要使用pd.melt()函数,可以将二维数据列表的数据框转换成一维数据列表。我们首先构造数据框df:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_4.jpg?sign=1739544609-EQaNCDmH6BwtslFwoFh9p1NsFofmibqi-0-bc4e4e14bdcf2876bb3cc3ab316051fc)
(1)将宽数据转换为长数据。将多行聚集成列,从而二维表变成一维表(见图2-2-1):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_1.jpg?sign=1739544609-5jzq1Cq5RxC6oxbopVogBWRjgyTY7SQ3-0-e3fe593bb6ac232c175e8ed69343af70)
图2-2-1 表格变换处理的示意案例
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_5.jpg?sign=1739544609-DVJcVNdl60vjG15bL4cWaeS78ayqYZpl-0-a495618dafaa5ec5da0a12d6822b1144)
其中,id.vars("x")表示由标识变量构成的向量,用于标识观测的变量;variable.name("year")表示用于保存原始变量名的变量的名称;value.name("value")表示用于保存原始值的名称。
(2)将长数据转换为宽数据。将一列根据变量展开为多行,从而一维表变二维表:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_36_6.jpg?sign=1739544609-k68o8acpV8juaQutFdvlzSAHr7vy93ly-0-fa7259d50b48b3ea84dcf29f4d0784ee)
2.2.5 变量的变换
有时候,我们需要对数据框某列的每个元素都进行运算处理,从而产生并添加新的列。我们可以直接对数据框的某列进行加减乘除某个数值的运算,从而产生新列:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_2.jpg?sign=1739544609-3SrF8luXhcSjAIS32JUPySSIuuE339O2-0-3feda2cf29da368640923c15e518495d)
使用Python的transform()函数,结合lamdba表达式可以为原数据框添加新的列,改变原变量列的值。同时结合条件语句的三元表达式ifelse()进行更加复杂的运算(见图2-2-2):
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_3.jpg?sign=1739544609-NJk5vYWGEbhixMeI4CEpVhMA1QOtYcia-0-1d63e47ea0cbe785a7f95abb32395711)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_37_4.jpg?sign=1739544609-voUaYOi4XPm0WRxnrlhnBYuist0KcmiK-0-4a4a4424a3cc29a49226e94b9df91c95)
图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=1739544609-bVIzcdgjEjuReV08LAvk2jBgO1uBfHFb-0-0b870713bf9a94d9ac98a6c994ba3fc7)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_2.jpg?sign=1739544609-r9h1AzOA0TONnqAmxuggM7fIqGAdxnGm-0-2d7a62eadb0dd55b429847270c79748e)
图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=1739544609-c8h3G0H4pm9tqLP8yuUSFVHiQ0iffqbj-0-ac4fd1c550ff7a6703199fddd249dd0e)
(1)数据框添加列或者横向添加表格:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_4.jpg?sign=1739544609-trKAsA9cUmqYV32A2VESypgKMfy0Z4in-0-daec8b4efbd3998b48ecd2a5cf98eea1)
其中axis表示沿纵轴(axis=0)或者横轴(axis=1)方向连接。(2)数据框添加行或者纵向添加表格:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_5.jpg?sign=1739544609-gVgcW1Q9LV5gKopbunb7exfkdOvoAOJH-0-848d1ef819efe25bdec46a616808c236)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_6.jpg?sign=1739544609-J3GBFqEHOF83uczVXjqivEkz0Pe6NK3G-0-a318c7148d295e81490cc539c3d07d80)
图2-2-4 表格拼接的示意案例
(3)可以添加行/列,也就可以删除某行/列,这时需要使用*.drop()函数.比如要删除df1的"y"列:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_38_7.jpg?sign=1739544609-Y8y3tNZKI0sFlbelqmuBycitqCs4TgPb-0-9522b26dad71af556186549910484a81)
其中,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=1739544609-YS3qS1hXl9OiJAzq2yPq1mdlr2Ut5yZq-0-1c6270954688192868afca404159ded8)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_2.jpg?sign=1739544609-6HzJtL5ZFOQkdzpwRFcak6zyy1v7wiyM-0-65f7f3f0b7cb6265969a7824314fe16a)
图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=1739544609-A55Ax9MLr9iS5ZPFrEsSACJSCAE87PMM-0-99e6ecb830d049ca5f522a30d0e01df1)
图2-2-6 pd.merge()函数融合表格的示意案例
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_39_4.jpg?sign=1739544609-8ovcH3ckXamL12XijVYsZc3QHv7xgTM1-0-44ef29b68544fc2dbf271b6095ee71e9)
图2-2-7 复杂的pd.merge()函数融合表格的示意案例
● 只保留左表的所有数据:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_1.jpg?sign=1739544609-AIDQ2CT2sKWSLm0O7LcZMvXthIlbkow0-0-6e4904d2a1c8aae9764fb4f1e345580f)
● 只保留右表的所有数据:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_2.jpg?sign=1739544609-ap1NyblWrtARmhvAmqwnzUTAhJaUkdMu-0-1c00e8d7415637eedbdef8a50fcaa893)
● 只保留两个表中公共部分的信息:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_3.jpg?sign=1739544609-oFeBt1SgLAPY2IO7lgLWTwQUopV97YAT-0-0c853adce0884410f933382e5c7f7d26)
● 保留两个表的所有信息:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_4.jpg?sign=1739544609-HNHM6GM564DW0RHqtR3EMMszUoaRT2SB-0-1f2f2dead722a986fe31199930ee5432)
● on=["x","y"]表示多列匹配:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_5.jpg?sign=1739544609-SFHwfUvn4BUGoP1hBLc7I9n7AmyBc4vP-0-100b4f25acdab94f3ad2fbf21c3f196b)
● left_on="x",right_on="g"可以根据两个表的不同列名合并:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_6.jpg?sign=1739544609-Mdjy6NltRR1aw3uiJ7p2p0u1a9NT2zWL-0-199e4a28ed706b9193c796cb203186e4)
● 如果在表合并的过程中,两个表有一列同名,但是值不同,合并时又都想保留下来,就可以用suffixes给每个表的重复列名增加后缀:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_7.jpg?sign=1739544609-IbB6K662HHBLthoTl0YJ8pbKoXol13FF-0-89fc150dd20e92d4e5b20422ff769191)
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=1739544609-JJh9wkQMjwto3FmUDuXvX30GrMBAg44k-0-c18a420cbc65aef0b5c5cbc560a54e7d)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_40_9.jpg?sign=1739544609-7egyJYsEHcTRcBe6IRY80rOfWCb9lA2X-0-0f130eadc61b48c71db57476fb1acf27)
图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=1739544609-Kh6a37NugPS5eKiCbuz4PN9EgetCOAmu-0-9f780af06d57bb9cc5eed7d78f00b44e)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_2.jpg?sign=1739544609-wAvd0QNz8IU3UWnsyr5TkyLG1n91EONz-0-37e4d46d1b4d0711e17740601652b549)
图2-2-9 df_melt的数据信息
1.按行或列操作
● 按行求和:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_3.jpg?sign=1739544609-1CvFZtjeVjPqyn0iOE1mnqWpSGTWej2v-0-328841d123c65776c06f5e1b2b40e5a9)
● 按列求和:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_4.jpg?sign=1739544609-u84UYQiAfWeZaTZkeoHnCFFFjGNrV9GU-0-e65a2e7ce280a7252009d3b2abe5c4ed)
● 单列运算:在Pandas中,DataFrame的一列就是一个Series,可以通过map或者apply函数来对某一列进行操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_5.jpg?sign=1739544609-DJZPiq0PWzrhDJpRJQoMqUCiYqibMhtL-0-9701c09adea79778bb4972d827a657fb)
● 多列运算:要对DataFrame的多个列同时进行运算,可以使用apply()函数。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_6.jpg?sign=1739544609-NjWkri5V5CgCI5hg4IkRgnwrE6SCOOxc-0-42c5355a9788df6d82e08c8f386a4266)
2.分组操作:groupby()函数
● 按year分组求均值,如图2-2-10所示:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_7.jpg?sign=1739544609-T0D11VRQkOEGTpNApwqfeCnXjpBTjCpU-0-afede9c1f077f620ade8ff1b325da95f)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_41_8.jpg?sign=1739544609-ivw8ak5Xt5Lcj4a2CZAMuSMklF0VdKJX-0-ab95624487f15b364666174f0783392e)
图2-2-10 按year分组求均值
● 按year和x两列变量分组求均值,如图2-2-11所示:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_1.jpg?sign=1739544609-JIhGtLBW0zbNqTmhisA3fe2mW7N6W0uy-0-37b328ce62b51b7e8e98cae296e17c25)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_4.jpg?sign=1739544609-xU70Wse8mz7AB37tGvXJHyq0ZsxpqSdb-0-d5859aad8c22258840f9faca714f65de)
图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=1739544609-c0WDOvGmk4yA3QEOzzqCBZiTfJn2nbKI-0-e9fed8ea250fb98033742cf754477930)
● 按year分组求方差:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_3.jpg?sign=1739544609-ySFhMVrShRJo6De2zHwLqSBCMhNtguSD-0-3904cc8d5ef4f25d0c58958ceeebc5bf)
3.分组聚合:aggregate()函数
aggregate()函数结合groupby()函数可以实现SQL中的分组聚合运算,如图2-2-12所示。aggregate()函数也可以简写为agg()。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_5.jpg?sign=1739544609-DNEbSIBvkMRek5iacYfEmDTh03EOlto5-0-406877dbb90d66a1ae37c970c99d50e8)
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_42_6.jpg?sign=1739544609-66ZzwKk61HddfyiHeVErH36sbQTUNnx6-0-6ea507ff4c69c69f35f574c684272580)
图2-2-12 aggregate分组聚结果
4.分组运算:transform()函数
transform()函数可以结合groupby来方便地实现类似SQL中的分组运算的操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_1.jpg?sign=1739544609-qBfEs7oXCLtXzvIk2qxQf3Xez1lqFcJE-0-274b151e600500bca4b1b45a06c3ef8e)
5.分组筛选:filter()函数
filter()函数可以结合groupby来方便地实现类似SQL中的分组筛选运算的操作。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_2.jpg?sign=1739544609-4MJvHzg3KzgVPc46u1bmTyVWlK9k0NTA-0-6feaf6553a07956423b04e2b9bc1d8ce)
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=1739544609-t5F3wz1VDJKDqdLcOHcYAhw6q6WlV0Rr-0-a0b6bd03647f3cef6cb6a8d6e0e9a589)
使用to_csv()函数,可以将DataFrame的数据存储为CSV文件:
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_43_4.jpg?sign=1739544609-Uyeno9AzFcFZ6PewYV04MDltQypW0pvp-0-1c4e2713a377b349b64ec2c3bbc58c6f)
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=1739544609-o2ueO8dGfOanuFIeLuLRGPseI3WEKO77-0-ec15b60be9f6e52c4114ba6f45ced5a0)
使用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=1739544609-45ckI3eg4tD1ZO4owv65jVpfn5IkyV9R-0-56b28e98e0c190bb4a64444d2cf9a45a)
其中,sheetname指定页面sheet,默认为0;header指定列名行,默认为0,即取第一行,数据为列名行以下的数据;若数据不含列名,则设定header=None。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_3.jpg?sign=1739544609-5AHkUUE3iYcc4OrkDCRPzPDscYIoN9UD-0-5dc0c491961609c28aaf84dec44d6083)
其中,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=1739544609-qmiN1sMc9lNlwG1OO36axCO9wh7TY2JK-0-6a3978b8e7adf1a3086a09b56db26626)
图2-2-13 一维数据列表
二维数据列表就是行和列都有字段,它们相交的位置是数值的表格。这类表格一般是由分类汇总得来的,既有分类,又有汇总,所以是通过一维数据列表加工处理过的,通常用于呈现展示,如图2-2-14所示。
![](https://epubservercos.yuewen.com/FF0186/16896237904364306/epubprivate/OEBPS/Images/38370_44_5.jpg?sign=1739544609-7kwBKXQbmRFsd0BBG5fLgJeJodE9nCxt-0-423fffd3a4ff5d7a4642e494e70f9dc2)
图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=1739544609-w0LWQy9hwmuJnkpKuqruW5VlxzQ4dM2W-0-b17bfe5ea579158bb3e100f1e40164ce)