### Pandas #### Pandas 简介 + Pandas (Panel data & data analysis), 是基于 Numpy 的专用于数据分析的工具 + Pandas 的主要数据结构是 **Series**(带标签的一维同构数组)与 **DataFrame**(带标签的,大小可变的,二维异构表格) + [Pandas 官档](https://www.pypandas.cn/docs/getting_started/dsintro.html#dataframe) #### Pandas 优势 + Pandas 适用于处理以下类型的数据: + 与 SQL 或 Excel 表类似的,含异构列的表格数据; + 有序和无序(非固定频率)的时间序列数据; + 带行列标签的矩阵数据,包括同构或异构型数据; + 任意其它形式的观测、统计数据集, 数据转入 Pandas 数据结构时不必事先标记。 + Pandas 优势 1. 处理浮点与非浮点数据里的缺失数据,表示为 NaN; 2. 大小可变:插入或删除 DataFrame 等多维对象的列; 3. 自动、显式数据对齐:显式地将对象与一组标签对齐,也可以忽略标签,在 Series、DataFrame 计算时自动与数据对齐; 4. 强大、灵活的分组(group by)功能:拆分-应用-组合数据集,聚合、转换数据; 5. 把 Python 和 NumPy 数据结构里不规则、不同索引的数据轻松地转换为 DataFrame 对象; 6. 基于智能标签,对大型数据集进行切片、花式索引、子集分解等操作; 7. 直观地合并(merge)、**连接(join)**数据集; 8. 灵活地重塑(reshape)、**透视(pivot)**数据集; 9. 轴支持结构化标签:一个刻度支持多个标签; 10. 成熟的 IO 工具:读取文本文件(CSV 等支持分隔符的文件)、Excel 文件、数据库等来源的数据,利用超快的 HDF5 格式保存 / 加载数据; 11. 时间序列:支持日期范围生成、频率转换、移动窗口统计、移动窗口线性回归、日期位移等时间序列功能。 #### 主要数据结构 1. Series 是**带标签的一维数组**,可存储整数、浮点数、字符串、Python 对象等类型的数据。轴标签统称为索引。 + 创建 : `pd.Series(self, data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)` + data 参数 支持以下数据类型 1. **Python 字典** : `pd.Series({'b': 1, 'a': 0, 'c': 2})` 2. **多维数组** : data 是多维数组时,index 长度必须与 data 长度一致。没有指定 index 参数时,创建数值型索引,即 [0, ..., len(data) - 1]。 3. **标量值(如,5)** : data 是标量值时,必须提供索引。Series 按索引长度重复该标量值。 + Series 属性 ```python import pandas as pd import numpy as np index = ["stu0", "stu1", "stu2", "stu3"] value = [ ["张三", 13, 1], ["李四", 32, 2], ["王五", 23, 1], ["小二", 12, 1], ] se = pd.Series(index=index, data=value) print(se) print(se.ndim) # 1 print(se.dtype) # object print(se.shape) # (4,) print(se.index) # Index(['stu0', 'stu1', 'stu2', 'stu3'], dtype='object') print(se.values) # [list(['张三', 13, 1]) list(['李四', 32, 2]) list(['王五', 23, 1]) list(['小二', 12, 1])] ``` 2. DataFrame 是由**多种类型的列构成的二维标签数据结构**,类似于 Excel 、SQL 表,或 Series 对象构成的字典。DataFrame 是最常用的 Pandas 对象,与 Series 一样, + `pd.DataFrame(self, data=None, index: Optional[Axes] = None, columns: Optional[Axes] = None, dtype: Optional[Dtype] = None, copy: bool = False,)` + 参数 | 参数 | 描述 | | ----------- | ---------------- | | **data** | 数据 | | **index** | 行索引 | | **columns** | 列索引 | | **copy** | 是否允许生成副本 | + DataFrame 支持多种类型的输入 1. 一维 ndarray、列表、字典、Series 字典 2. 二维 numpy.ndarray 3. 结构多维数组或记录多维数组 1. Series 2. DataFrame + 创建方式 1. 逐个传入行列与数据信息 ```python import pandas as pd # 创建 DataFrame # 一、逐个传入行索引、列索引、数据部分 # 行索引 index = ["stu0", "stu1", "stu2", "stu3"] # 列索引 columns = ["name", "age", "group"] # 数据部分 value = [ ["张三", 13, 1], ["李四", 32, 2], ["王五", 23, 1], ["小二", 12, 1], ] df = pd.DataFrame(data=value, index=index, columns=columns) """ name age group stu0 张三 13 1 stu1 李四 32 2 stu2 王五 23 1 stu3 小二 12 1 """ ``` 2. 字典形式传入数据 (以列名称作为字典的 key, 每一列的值作为字典的 values) ```python import pandas as pd # 创建 DataFrame # 二、字典形式传入数据 index = ["stu0", "stu1", "stu2", "stu3"] dict1 = { "name": ["张三", "李四", "王五", "小二",], "age": [12, 21, 32, 32], "group": [1, 2, 1, 1], } df1 = pd.DataFrame(dict1, index=index) print(df1) """ name age group stu0 张三 12 1 stu1 李四 21 2 stu2 王五 32 1 stu3 小二 32 1 """ ``` + 属性 + **shape** : 行列数 + **ndim** : 维度 + **size** : 大小 (内部数据数目) + **dtypes** : DataFrame 内属性类型, 以列数返回,多种类型的话向上选取数据类型,字符串返回为 object 而非 string + **values** : 数据部分 + **index** : 行索引 + **columns** : 列索引 + 修改索引 1. 修改整个行索引 : `df.columns = 新的行索引` 2. 修改列部分索引名称 : `df.rename(columns={"旧名称1": "新名称1", "旧名称2": "新名称2"}, inplace=True)` 3. 修改行部分索引名称 : `df.rename(index={"旧名称1": "新名称1", "旧名称2": "新名称2"}, inplace=True)` #### Pandas 读写数据 + Pandas 读取到的文件会保存为 DataFrame 数据. + Pandas 一般读取 csv、txt、excel 文件(.xlsx 与 .xls) ##### 文本文件读取 + 读取方式常为 `pd.read_文件格式()` + 参数 | 参数 | 描述 | | ------------------------------- | ------------------------------------------------------------ | | **filepath_or_buffer** | FilePathOrBuffer : 文件路径及文件名 或者缓存 | | **sep=","**、**delimiter=None** | 分隔符 delimiter 与 sep 同时只可以出现一个 | | **encoding** | 编码方式 | | **header="infer"** | 自动识别列索引,也可以将值设为列索引的指定行 **header="2"** | | **index_col=None** | 选择某一列作为行索引 | | **nrows=None** | 取出行数,默认取出所有 | | **usecols=None** | 需要选择哪些列,默认None
 1. **None** 读取所有列
 2. **int** 读取第几列
 3. **list** int 列表 读取这个列表中对应的列
 4. **string** excel的方式读取,例如:"A:F"表示A到F列,"A,D,E:H"表示A和D和E到H列 | | **names=None** | 对读取的列重命名,也可以读取数据之后再重命名 | | **sheet_name=0** | 读Excel的时候读取指定名称的表单,也可以是索引,默认0 | | **skiprows=None** | 跳过哪些行 | | **keep_default_na** | 是否保留空值,默认True | | **dtype** | 设置列的类型,例如,{‘a’: np.float64, ‘b’: np.int32} | ##### 写入文本文件 + 写入方式 : `DF_name.to_保存类型()` + 参数 | 参数 | 描述 | | -------------------------------------------------- | ------------------------------------------------------------ | | **path_or_buf: Optional[FilePathOrBuffer] = None** | 保存文件路径和文件名 | | **sep: str = ","** | 分隔符 | | **float_format: Optional[str] = None** | 写浮点数的格式,’%.0f’ | | **header: Union[bool_t, List[str]] = True** | 是否输出表头 (将列索引保存到文档中),默认True | | **index: bool_t = True** | 是否输出索引 (将行索引保存到文档中),默认True | | **columns: Optional[Sequence[Label]] = None** | 列名称,可以是列表形式,表示存储的列 | | **mode: str = "w"** | 设置写入模式,默认"w" | | **sheet_name** | **Excel专有**,表单名称,默认"Sheet1"
 可以指定为 **int** 代表分表的序号,从 0 (代表第一个表) 开始
 也可以指定为分表的名称 | + 特殊情况 : 写入excel 文件 + 将不同的 dataframe 保存到同一个 excel 的不同 sheet 中去 + 在 同一个 sheet 中添加数据 + 实例 ```python import numpy as np import pandas as pd index = ["stu0", "stu1", "stu2", "stu3"] dict1 = { "name": ["张三", "李四", "王五", "小二", ], "age": [12, 21, 32, 32], "group": [1, 2, 1, 1], } df1 = pd.DataFrame(dict1, index=index) writer = pd.ExcelWriter('../read_excel/学生信息.xlsx') df1.to_excel( excel_writer=writer, index=False, sheet_name="0" ) df1.to_excel( excel_writer=writer, index=False, header=False, startrow=5, sheet_name="0" ) writer.close() ``` #### DataFrame 查询 ##### DataFrame 的索引(查询操作) 1. 直接索引 + **对单列数据的访问**:DataFrame 的单列数据为一个 Series。根据 DataFrame 的定义可以 知晓 DataFrame 是一个带有标签的二维数组,每个标签相当每一列的列名。有以下两种方式 来实现对单列数据的访问。 1. 以字典访问某一个 key 的值的方式使用对应的列名,实现单列数据的访问。 2. 以属性的方式访问,实现单列数据的访问 + 查询实例 + 访问某些列 : `df_name[ [列索引1, 列索引2, ...] ]` + 访问某些行的某些列 : `df_name[ [列索引1, 列索引2, ...] ][ 行下标1: 行下标2]` 或 `df_name[ 行下标1 : 行下标2][ [列索引1, 列索引2, ...] ]` + 实例 ```python import pandas as pd index = ["stu0", "stu1", "stu2", "stu3"] columns = ["name", "age", "group"] # 数据部分 value = [["壮壮", 19, 1], ["大壮", 20, 2], ["张杰", 19, 1], ["樊浩", 17, 2]] df = pd.DataFrame(index=index, columns=columns, data=value) out = df["name"] # print(df) """ name age group stu0 壮壮 19 1 stu1 大壮 20 2 stu2 张杰 19 1 stu3 樊浩 17 2 """ # 1. 使用索引名称 print(out["stu1"]) # 大壮 # 2. 使用索引下标 print(out[2]) # 张杰 # 3. 使用索引名称的切片 print(out["stu2":"stu2"]) """ stu2 张杰 Name: name, dtype: object """ # 4. 使用索引下标的切片 print(out[2:3]) """ stu2 张杰 Name: name, dtype: object """ # 5. 使用索引名称的列表 print(out[["stu1"]]) """ stu1 大壮 Name: name, dtype: object """ # 6. 使用索引下标的列表 print(out[[2]]) """ stu2 张杰 Name: name, dtype: object """ # 7. head 的形式 print(out.head(3)) """ stu0 壮壮 stu1 大壮 stu2 张杰 Name: name, dtype: object """ # 8. tail 的形式 print(out.tail(3)) """ stu1 大壮 stu2 张杰 stu3 樊浩 Name: name, dtype: object """ # 访问多个值 print(out["stu0":"stu3"]) """ stu0 壮壮 stu1 大壮 stu2 张杰 stu3 樊浩 Name: name, dtype: object """ print(out[["stu1", "stu2"]]) """ stu1 大壮 stu2 张杰 Name: name, dtype: object """ print(out[1:3]) """ stu1 大壮 stu2 张杰 Name: name, dtype: object """ ``` 2. loc 与 iloc 索引方式 + `DF_name.loc[行信息, 列信息]` 同时获取指定范围内的行列数据 ,不可以使用下标 + **行信息** : 起始行值 : 结束行值; 也可以使用 关键字/布尔索引 + **列信息** : 起始列值 : 结尾列值; 也可以使用 关键字/布尔索引 + `DF_name.iloc[]` 同时行列索引, 只能使用下标