![Python大数据与机器学习实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/134/30638134/b_30638134.jpg)
3.1 数据对象
Pandas中最重要的两种数据对象是Series和DataFrame,其中DataFrame由多个Series组成,而索引是DataFrame和Series的重要组成部分,下面介绍它们的概念及基本用法。
3.1.1 Series对象
上一章介绍的Numpy多维数组常用于处理单一类型的数据,可看作列表的扩展;而Series可以管理多种类型的数据,可以通过索引值访问元素,更像基本数据类型中字典的扩展,可以把它视为带索引的一维数组。下面将从创建、查询、添加、删除等几方面学习Series的使用方法。
1.创建
创建Series需要指定值和索引,当不指定索引时,索引为元素的序号。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_1.jpg?sign=1739201344-L5Cpz6tCpwz3eOzzJ8XH0YF3zykfpXb7-0-dcb09f4827229a38ab4811ba531a1765)
也可以使用转换的方式将其他类型的数据转换成Series类型。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_2.jpg?sign=1739201344-sedtz6SUgcPZcvqiNvvNxhfCfYouhTrC-0-412fdd2a0a779580a9faa297d36f6b87)
2.查询
Series支持用索引值访问其中的数据,这种操作类似于访问字典元素;也可以用位置下标访问数据元素,操作方法类似于访问列表元素。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_3.jpg?sign=1739201344-cJk0ABeTjZwzX6wBKTUDywZbVK1wFBDk-0-8070aab79ff4d80a4176761b667c2cbc)
Series由两个数组组成,其数据值和索引值可作为属性访问。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_4.jpg?sign=1739201344-XTVSiCTR5R7nOweoz89KrrhAf45feVVa-0-06bca65c90488d782fa2627ff42214b4)
Series还提供多维数组对象接口,用于处理多维数组的函数都可直接处理Series元素。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_5.jpg?sign=1739201344-0z2Utnb6EJ9c89plvV2GB1MrU8xcISxD-0-0199e71062c89c5ad687ea826c693b17)
通过索引列表、下标列表、下标切片的方式可以访问Series中的一个或多个元素。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_72_6.jpg?sign=1739201344-QGXEenhFShwRKtvw5fo96tCWJom3Cb4e-0-4b9fc2f137ec61e0afce682a247b0aa6)
还可以通过Series的iteritems方法以迭代的方式遍历元素。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_1.jpg?sign=1739201344-jrq7EASTtr70hsNcvXTDSl8vOXLNCgri-0-33696a2654a36e2e39786d9662e42eff)
3.添加
用append方法连接两个已有的Series,并返回新的Series,且不改变原数据。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_2.jpg?sign=1739201344-OS6cPQfqEk5Ja8j3jvBYjCIwGHzI78B1-0-90fa71135d9a4b1b370c0dcec977a0ff)
4.删除
用drop方法删除索引值对应的Series元素,并返回删除后的Series,且不改变原数据。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_3.jpg?sign=1739201344-gG85IuBUSrQhXiYtMdUiqKZ14jY7THbO-0-86697fee91aeeea43c0df2297ff6adf6)
3.1.2 DataFrame对象
DataFrame类似于数据库中的数据表table,是数据处理中最常用的数据对象。从数据结构的角度可将其视为有标签的二维数组,横向为行,纵向为列,且每行有行索引,每列有列名,列中数据类型必须一致。
1.创建
利用转换方式将已有数据转换成DataFrame,其语法如下:
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_4.jpg?sign=1739201344-nt4DFvqgKpE2qNfilXvbAdu6sWqKlyWj-0-c6007983e778d61405f016b1206d71b3)
其中,data是待转换的数据,index是索引值(行),column是列名。下例通过数组组成的字典创建DataFrame。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_5.jpg?sign=1739201344-pt4KppuVJwLrjdy5RfFVw2jNO7fGt2gk-0-d4480283bb1512bfbe8a1c8c3ce439d3)
在通过字典组成的数组创建DataFrame时,如果不指定索引,则以数据的序号作为索引,使用Series创建Dataframe与之同理。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_73_6.jpg?sign=1739201344-d5hrXdcvwmLqekJhKdwWS4EPu8dwW8H3-0-ccfa27bbc2c7f7e59cbb0807ce206808)
通过数组创建DataFrame,用columns指定列名。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_74_2.jpg?sign=1739201344-SlxxaYw6XnSvUd0Do1cWZmZf35vIPzt9-0-3672e2dc7f09b89ab0f3236273374167)
2.添加
用append函数可以在当前DataFrame的尾部添加一行,然后返回新表。添加的内容可以是列表、字典、Series,本例中以字典为例示范append函数的使用方法。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_74_3.jpg?sign=1739201344-wrvrEUOmjOP1NKUqlaDMizl6u9ipv4S9-0-c8e64d98a3d1e16d3492005d9544413d)
如果想在两行之间插入数据,则可以先用索引值将DataFrame切分成前后两个表,然后将前表、新行、后表连接在一起。
除了添加一行,append函数还支持将两个DataFrame表连接在一起,支持表连接的函数还有concat。下例中,将df表和其自身连接起来,使用ignore_index=True忽略索引值,索引值重新排序。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_74_4.jpg?sign=1739201344-EsFlbMhQFl15IgYBf7ginO48GuuoCf4B-0-977d3b310296bc6e9cd37e102074d56c)
添加列最简单的方法是直接给新列赋值:
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_74_5.jpg?sign=1739201344-YKWp1s5OlcQCjqiYOjxjraqVHk4wbgpt-0-280c232eb9a69eeaa66e3c13968162dd)
如果需要在指定位置插入新列,则需要用insert方法。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_75_1.jpg?sign=1739201344-7OM5zJd1QiEFVJuhrRyZVAvzoFl4X2rB-0-f327c7a1cf4b4c93336d09c5c650e4b9)
3.删除
用drop方法可以删除DataFrame的行和列。在删除列时,需要指定参数axis=1;当该参数默认为0时,即删除行。drop方法支持删除一行/多行或一列/多列,在删除行时需要指定行的索引值。在本例中,删除第1行后,仅剩第0行。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_75_2.jpg?sign=1739201344-lr1GHZDWoaJu6ZYgyBKN4T1o9jhLofZ9-0-953af03cb5ece286e4b3f5247c1830dd)
在删除列时需要指定列名,drop方法默认返回删除列后的数据表,原表不变。当指定其参数inplace=True时,原数据表内容被修改。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_75_3.jpg?sign=1739201344-hVbAJie7sqOj6MIBnluVnFqjot4sc0s4-0-4730d1e8eb1565f67dd51eb555e9b300)
用del方法也可以从原表中删除a列。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_75_4.jpg?sign=1739201344-a33AUe4bVPa5JKOWgqiZw4lDyg6p53mF-0-0ce36425a66026c286032aa334054a05)
还可以用pop方法删除列,调用pop方法之后,b列的内容作为函数返回值并同时从原表中删除。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_75_5.jpg?sign=1739201344-6QFRT8AP49cxUD2riqYfPMVprpp6jJvc-0-d19f2cfaebafa46037861326c10e2872)
3.1.3 Index对象
1.索引
DataFrame中的索引包括行索引和列索引,其类型为Pandas.Index,简称为pd.Index。它的结构类似于数组,但其数据内容不可以修改(不允许单个修改,但可以对行索引或列索引整体重新赋值)。在理论上,索引中允许内容重复,在数据表中允许有重名的列或者行索引值,但一般不推荐使用。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_76_2.jpg?sign=1739201344-WDvGgumYuDuoKT4Z8EhPNzTYYTfwmAEV-0-e7d9f526684ea1537b56ac83410a7064)
用pd.Index将其他类型转换成索引对象。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_76_3.jpg?sign=1739201344-Ul9ESWki2N5RQJIDXm5RD5ls8901W5Xz-0-baedb8ffd2470841ad0eb2d2b62d6c2e)
用values属性查看Index中的所有值。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_76_4.jpg?sign=1739201344-pU4PxBdPjFVpDK4gtY9XI6wMRlL0vUMS-0-88f9420b204524a8d40dae550a8d971e)
用下标或下标数组读取部分索引值。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_76_5.jpg?sign=1739201344-5EQ8hTY21rWvYDfyh1i1Lfascg2KS3HQ-0-d2b2f1cc5f8c1db52b004296c7a9a63e)
用get_loc或get_indexer查找值对应的下标。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_76_6.jpg?sign=1739201344-YyqQ0A2RLS2NWRAJhl3akzT46zfJrcsq-0-2915c364fbd980ccd0e9f8f057656583)
2.修改索引
对DataFrame的column和index重新赋值可改变其索引,数据表内容不变。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_77_1.jpg?sign=1739201344-OflcausuOgKQ7DJMLuNrifi2umUX2GIk-0-93e4e023d9b4a88ecb427229319a2770)
如果不仅仅想改变索引值,还想重排行或列的顺序,可以使用DataFrame的reindex方法。从下列返回结果可以看到,reindex方法返回了新的数据表,原表不改变。对于已有的索引值,对应行的顺序发生了变化;对于不存在的索引值,生成了新的行并置为空值。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_77_2.jpg?sign=1739201344-MhlWZPGP9k4wH1WOJ9RJX6pq1zRmrhGV-0-4f60be46704016ff0707b3cd13b48fad)
除了对行修改,reindex方法还支持修改列索引,用columns参数指定其新的列索引值。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_77_3.jpg?sign=1739201344-UohdDJFeZw2CtgzMTOU2KUWqZl01LHVN-0-1bc32a5ef67b05076e4cdbc6105eec5d)
用sort_index方法对索引重新排序,该方法默认返回新的DataFrame。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_77_4.jpg?sign=1739201344-alza5li8vJpEN7ShwFy0uN0SZfv5kipe-0-a39275ad83ee0ae5c48715edf8e3cc64)
还有一种更为简单的方法,即用直接赋值的方法修改其列索引的顺序。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_77_5.jpg?sign=1739201344-8tLUGw4peOgsYXxGcGnstE6Ly2y5XrfW-0-3260b8415da769bf2563f4802b4781cb)
3.多重索引
多重索引包括多重行索引和多重列索引,在数据分析和建模过程中使用多重索引的情况并不多。多重列索引主要出现在从其他格式文件导入数据和导出数据,以及前期的数据处理过程中,如从Excel文件中导入的表格,如表3.1所示。
表3.1 Excel多重列索引数据
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_78_1.jpg?sign=1739201344-wGmSiJk9nDWj6pDRDKvysMiJyZR7Uk2v-0-31042e0aa7a6a3bdfbc54c07bd6dc9cc)
用read_excel方法读取数据表(读取Excel需要第三方库支持,具体方法请参见第5章),注意用header参数指定列索引包含前两行(读取双重行索引使用index_col=[0,1])。从返回结果可以看到,其每个字段被表示为多层列名组成的元组。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_78_2.jpg?sign=1739201344-LV3RI20fqcwRZXwZA2s36l1b8mVxjNNy-0-412da216aa56a34402ee39f7036e0813)
由于数据被解析成多重索引处理起来比较麻烦,因此一般会将其两列索引组合成单层索引。下例用join方法将元组连成的字符串作为新的字段名。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_78_3.jpg?sign=1739201344-G8Ue7AyaEVfgL6ZP5VuxYauQ62qhFALu-0-ac6d28a5727abdc4dfdc073c7a22d33a)
多重行索引常出现在groupby用多变量分组后的数据中(groupby将在3.3节中详细介绍,本例中代码的前三行只作为数据源使用,主要关注将索引转换为普通列的方法),在这种情况下,通常使用reset_index方法将多重行索引转换成普通列。创建多重行索引数据:
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_78_4.jpg?sign=1739201344-YYmYQx8xnr2gq8GQbNLRe7t7OBNnxFv7-0-b24030c82697ab0da375191019f275fe)
从运行结果可以看到,行索引为AGE和OWNRENT两层。在使用reset_index方法后,索引被转换为普通列。
![](https://epubservercos.yuewen.com/57F11A/16699150105739906/epubprivate/OEBPS/Images/38425_79_2.jpg?sign=1739201344-MiGxhZxuYq3pVFXnC27dj9UOoWwBGQ5S-0-e075f061ab612b86238904c4f74fbeb5)