## Pandas的应用 Pandas是Wes McKinney在2008年开发的一个强大的**分析结构化数据**的工具集。Pandas以NumPy为基础(数据表示和运算),提供了用于数据处理的函数和方法,对数据分析和数据挖掘提供了很好的支持;同时Pandas还可以跟数据可视化工具Matplotlib很好的整合在一起,非常轻松愉快的实现数据的可视化展示。 Pandas核心的数据类型是`Series`(数据系列)、`DataFrame`(数据表/数据框),分别用于处理一维和二维的数据,除此之外还有一个名为`Index`的类型及其子类型,它为`Series`和`DataFrame`提供了索引功能。日常工作中以`DataFrame`使用最为广泛,因为二维的数据本质就是一个有行有列的表格(想一想Excel电子表格和关系型数据库中的二维表)。上述这些类型都提供了大量的处理数据的方法,数据分析师可以以此为基础实现对数据的各种常规处理。 ### Series的应用 Pandas库中的`Series`对象可以用来表示一维数据结构,跟数组非常类似,但是多了一些额外的功能。`Series`的内部结构包含了两个数组,其中一个用来保存数据,另一个用来保存数据的索引,如下图所示。 ![](res/pandas-series.png) #### 创建Series对象 > **提示**:在执行下面的代码之前,请先导入pandas以及相关的库文件,具体的做法可以参考上一章。 - 方法1:通过列表或数组创建Series对象。 代码: ```Python # data参数表示数据,index参数表示索引标签 # 如果没有指定index属性,默认使用数字索引 ser1 = pd.Series(data=[320, 180, 300, 405], index=['一季度', '二季度', '三季度', '四季度']) ser1 ``` 输出: ``` 一季度 320 二季度 180 三季度 300 四季度 405 dtype: int64 ``` - 方法2:通过字典创建Series对象。 代码: ```Python # 字典中的键就是索引标签,字典中的值就是数据 ser2 = pd.Series({'一季度': 320, '二季度': 180, '三季度': 300, '四季度': 405}) ser2 ``` 输出: ``` 一季度 320 二季度 180 三季度 300 四季度 405 dtype: int64 ``` #### 索引和切片 跟数组一样,Series对象也可以进行索引和切片操作,不同的是Series对象因为内部维护了一个保存索引的数组,所以除了可以使用整数索引通过位置检索数据外,还可以通过自己设置的索引标签获取对应的数据。 - 使用正负向整数索引 代码: ```Python print(ser2[0], ser2[2], ser2[-1]) ser2[0], ser2[-1] = 350, 360 print(ser2) ``` 输出: ``` 320 300 405 一季度 350 二季度 180 三季度 300 四季度 360 dtype: int64 ``` - 使用自己设置的标签索引 代码: ```Python print(ser2['一季度'], ser2['三季度']) ser2['一季度'] = 380 print(ser2) ``` 输出: ``` 350 300 一季度 380 二季度 180 三季度 300 四季度 360 dtype: int64 ``` - 切片操作 代码: ```Python print(ser2[1:3]) print(ser2['二季度':'四季度']) ``` 输出: ``` 二季度 180 三季度 300 dtype: int64 二季度 500 三季度 500 四季度 520 dtype: int64 ``` 代码: ```Python ser2[1:3] = 400, 500 ser2 ``` 输出: ``` 一季度 380 二季度 400 三季度 500 四季度 360 dtype: int64 ``` - 花式索引 代码: ```Python print(ser2[['二季度', '四季度']]) ser2[['二季度', '四季度']] = 500, 520 print(ser2) ``` 输出: ``` 二季度 400 四季度 360 dtype: int64 一季度 380 二季度 500 三季度 500 四季度 520 dtype: int64 ``` - 布尔索引 代码: ```Python ser2[ser2 >= 500] ``` 输出: ``` 二季度 500 三季度 500 四季度 520 dtype: int64 ``` ####属性和方法 Series对象的常用属性如下表所示。 | 属性 | 说明 | | ------------------------- | --------------------------------------- | | `dtype` / `dtypes` | 返回`Series`对象的数据类型 | | `hasnans` | 判断`Series`对象中有没有空值 | | `at` / `iat` | 通过索引访问`Series`对象中的单个值 | | `loc` / `iloc` | 通过一组索引访问`Series`对象中的一组值 | | `index` | 返回`Series`对象的索引 | | `is_monotonic` | 判断`Series`对象中的数据是否单调 | | `is_monotonic_increasing` | 判断`Series`对象中的数据是否单调递增 | | `is_monotonic_decreasing` | 判断`Series`对象中的数据是否单调递减 | | `is_unique` | 判断`Series`对象中的数据是否独一无二 | | `size` | 返回`Series`对象中元素的个数 | | `values` | 以`ndarray`的方式返回`Series`对象中的值 | `Series`对象的方法很多,我们通过下面的代码为大家介绍一些常用的方法。 - 统计相关方法 代码: ```Python # 求和 print(ser2.sum()) # 求均值 print(ser2.mean()) # 求最大 print(ser2.max()) # 求最小 print(ser2.min()) # 计数 print(ser2.count()) # 求标准差 print(ser2.std()) # 求方差 print(ser2.var()) # 求中位数 print(ser2.median()) ``` 输出: ``` 1900 475.0 520 380 4 64.03124237432849 4100.0 500.0 ``` `Series`对象还有一个名为`describe()`的方法,可以获得上述所有的描述性统计信息,如下所示。 代码: ```Python ser2.describe() ``` 输出: ``` count 4.000000 mean 475.000000 std 64.031242 min 380.000000 25% 470.000000 50% 500.000000 75% 505.000000 max 520.000000 dtype: float64 ``` > **提示**:因为`describe()`返回的也是一个`Series`对象,所以也可以用`ser2.describe()['mean']`来获取平均值。 如果`Series`对象的数据中有重复元素,我们可以使用`unique()`方法获得去重之后的`Series`对象,如果想要统计重复元素重复的次数,可以使用`value_counts()`方法,这个方法会返回一个`Series`对象,它的索引就是原来的`Series`对象中的元素,而每个元素出现的次数就是返回的`Series`对象中的数据,在默认情况下会按照元素出现次数做降序排列。 代码: ```Python ser3 = pd.Series(data=['apple', 'banana', 'apple', 'pitaya', 'apple', 'pitaya', 'durian']) ser3.value_counts() ``` 输出: ``` apple 3 pitaya 2 durian 1 banana 1 dtype: int64 ``` - 数据处理方法 `Series`对象的`dropna`和`fillna`方法分别用来删除空值和填充空值,具体的用法如下所示。 ```Python ser4 = pd.Series(data=[10, 20, np.NaN, 30, np.NaN]) ser4.dropna() ``` 输出: ``` 0 10.0 1 20.0 3 30.0 dtype: float64 ``` 代码: ```Python # 将空值填充为40 ser4.fillna(value=40) ``` 输出: ``` 0 10.0 1 20.0 2 40.0 3 30.0 4 40.0 dtype: float64 ``` 代码: ```Python # backfill或bfill表示用后一个元素的值填充空值 # ffill或pad表示用前一个元素的值填充空值 ser4.fillna(method='ffill') ``` 输出: ``` 0 10.0 1 20.0 2 20.0 3 30.0 4 30.0 dtype: float64 ``` 需要提醒大家注意的是,`dropna`和`fillna`方法都有一个名为`inplace`的参数,它的默认值是`False`,表示删除空值或填充空值不会修改原来的`Series`对象,而是返回一个新的`Series`对象来表示删除或填充空值后的数据系列,如果将`inplace`参数的值修改为`True`,那么删除或填充空值会就地操作,直接修改原来的`Series`对象,那么方法的返回值是`None`。后面我们会接触到的很多方法,包括`DataFrame`对象的很多方法都会有这个参数,它们的意义跟这里是一样的。 `Series`对象的`apply`和`map`方法可以用于对数据进行处理,代码如下所示。 `Series`对象的`mask`和`where`方法可以将满足或不满足条件的值进行替换。 `Series`对象的`sort_index`和`sort_values`方法可以用于对索引和数据的排序,具体的用法请参考下面的例子。 `Series`对象的`value_counts`方法可以统计每个值出现的次数并且以从大到小的顺序进行排列,`Series`对象的`unique`方法可以获取到不重复的值。 #### 绘制图表 Series对象有一个名为`plot`的方法可以用来生成图表,如果选择生成折线图、散点图、柱状图等,默认会使用Series对象的索引作为横坐标,使用Series对象的数据作为纵坐标。 利用Series对象的数据也可以生成表示占比的饼图和显示数据分布的直方图,如下面的代码所示。 ### DataFrame的应用 #### 创建DataFrame对象 #### 基本属性和方法 #### 索引和切片 #### 相关运算 #### 缺失值处理 #### 数据离散化 #### 数据的合并 #### 交叉表和透视表 1. 交叉表:根据一个数据系列计算另一个数据系列的统计结果得到的`DataFrame`对象。 2. 透视表:将`DataFrame`的列分别作为行索引和列索引,然后对指定的列应用聚合函数得到的结果。 #### 分组和聚合 #### 绘制图表