Pandas第二章 基础

Pandas第二章 基础 一.文件的读取和写入1.文件读取1基础读取方法pandas 支持读取csv、excel、txt三类常见文件对应核心函数如下文件类型读取函数示例代码CSVpd.read_csv()df_csv pd.read_csv(../data/my_csv.csv)Excelpd.read_excel()df_excel pd.read_excel(../data/my_excel.xlsx)TXTpd.read_table()df_txt pd.read_table(../data/my_table.txt)2常用公共参数三类函数通用这些参数可以在read_csv/read_excel/read_table中混用用于精细化控制读取行为参数名作用示例headerNone不将文件第一行作为列名自动生成数字列名pd.read_table(../data/my_table.txt, headerNone)index_col指定一列或多列作为 DataFrame 索引pd.read_csv(../data/my_csv.csv, index_col[col1, col2])usecols仅读取指定列集合减少内存占用pd.read_table(../data/my_table.txt, usecols[col1, col2])parse_dates将指定列解析为 datetime 时间类型pd.read_csv(../data/my_csv.csv, parse_dates[col5])nrows仅读取前 N 行数据适合预览大文件pd.read_excel(../data/my_excel.xlsx, nrows2)3TXT 文件特殊分隔符处理read_table默认以空白字符为分隔符若 TXT 使用自定义分隔符如||||需通过sep参数指定注意sep是正则表达式参数特殊字符如|需要转义为\\|必须指定引擎使用多字符分隔符时需添加enginepython避免报错# 读取以 |||| 分隔的 TXT 文件 pd.read_table( ../data/my_table_special_sep.txt, sep\\|\\|\\|\\|, enginepython )注读取大文件时优先用usecols和nrows减少数据加载量时间列务必用parse_dates提前解析避免后续类型转换麻烦自定义分隔符的 TXT 文件记得对|等特殊字符做正则转义并指定enginepython2.基础文件写入1基础写入方法pandas 中 DataFrame 写入文件的核心操作强烈建议设置indexFalse避免无意义的索引列被写入文件目标文件类型写入函数示例代码CSVdf.to_csv()df_csv.to_csv(../data/my_csv_saved.csv, indexFalse)Exceldf.to_excel()df_excel.to_excel(../data/my_excel_saved.xlsx, indexFalse)TXT用df.to_csv()实现df_txt.to_csv(../data/my_txt_saved.txt, sep\t, indexFalse)注意pandas 没有to_table()函数TXT 文件需通过to_csv() 自定义分隔符实现常用制表符\t作为分隔。2格式转换输出Markdown / LaTeX如果需要将表格快速转换为文档格式可使用以下函数需先安装tabulate包目标格式转换函数示例代码Markdowndf.to_markdown()print(df_csv.to_markdown())LaTeXdf.to_latex()print(df_csv.to_latex())输出效果示例Markdown 格式| | col1 | col2 | col3 | col4 | col5 | |----|--------|--------|--------|---------|-----------| | 0 | 2 | a | 1.4 | apple | 2020/1/1 | | 1 | 3 | b | 3.4 | banana | 2020/1/2 | | 2 | 6 | c | 2.5 | orange | 2020/1/5 | | 3 | 5 | d | 3.2 | lemon | 2020/1/7 |LaTeX 格式\begin{tabular}{lr lr ll} \toprule {} col1 col2 col3 col4 col5 \\ \midrule 0 2 a 1.4 apple 2020/1/1 \\ 1 3 b 3.4 banana 2020/1/2 \\ 2 6 c 2.5 orange 2020/1/5 \\ 3 5 d 3.2 lemon 2020/1/7 \\ \bottomrule \end{tabular}注索引控制indexFalse是写入文件的最佳实践可避免生成冗余索引列。TXT 分隔符写入 TXT 时sep参数可自定义如sep,或sep|需与读取时的分隔符保持一致。二.基本数据结构1.Series一维数据结构1基本概念Series 是 pandas 中存储一维数据的核心结构由 4 个部分组成data序列的值index索引可自定义名称默认为空dtype数据存储类型name序列本身的名字import pandas as pd s pd.Series( data [100, a, {dic1:5}], index pd.Index([id1, 20, third], namemy_idx), dtype object, name my_name )2核心属性获取属性作用示例代码s.values获取序列值数组array([100, a, {dic1: 5}], dtypeobject)s.index获取索引对象Index([id1, 20, third], dtypeobject, namemy_idx)s.dtype获取数据类型dtype(O)object 类型s.name获取序列名称my_names.shape获取序列长度(n,)object 类型说明代表混合类型可存储整数、字符串、字典等不同 Python 对象纯字符串序列也默认是 object 类型也可使用string类型存储。2.DataFrame二维数据结构DataFrame 是在 Series 基础上增加了列索引用于存储二维表格数据由二维数据 行索引 列索引构成。1 两种常见创建方式方式 1二维列表 行列索引data [[1, a, 1.2], [2, b, 2.2], [3, c, 3.2]] df pd.DataFrame( data data, index [row_%d%i for i in range(3)], columns[col_0, col_1, col_2] )方式 2字典映射更常用df pd.DataFrame( data { col_0: [1,2,3], col_1: list(abc), col_2: [1.2, 2.2, 3.2] }, index [row_%d%i for i in range(3)] )2列选取选取方式语法返回结果选取单列df[col_0]Series选取多列df[[col_0, col_1]]DataFrame3核心属性获取属性作用示例代码df.values获取二维数据数组array([[1, a, 1.2], [2, b, 2.2], [3, c, 3.2]], dtypeobject)df.index获取行索引Index([row_0, row_1, row_2], dtypeobject)df.columns获取列索引Index([col_0, col_1, col_2], dtypeobject)df.dtypes获取各列数据类型返回 Seriescol_0: int64, col_1: object, col_2: float64df.shape获取行列数(3, 3)df.T转置 DataFrame行变列、列变行行列互换后的新 DataFrame联系DataFrame 的每一列本质上都是一个 Series列与列之间可以是不同数据类型。三.常用基本函数1.汇总函数head()/tail()函数作用示例默认值df.head(n)返回前n行df.head(2)→ 返回前 2 行n5df.tail(n)返回后n行df.tail(3)→ 返回后 3 行n5用途快速查看数据格式、字段和样本避免加载全量数据。2.信息概览函数info()df.info()用于查看数据集基础结构信息数据类型class pandas.core.frame.DataFrame行数RangeIndex: 200 entries, 0 to 199共 200 行列信息列名、非空值数量、数据类型内存占用memory usage: 11.1 KB3.统计描述函数describe()df.describe()仅对数值型列生成统计量统计量含义count非空样本数mean均值std标准差min最小值25%/50%/75%下四分位数 / 中位数 / 上四分位数max最大值注head()/tail()适合快速预览info()适合检查缺失值和数据类型describe()适合快速了解数值分布。若需对文本 / 分类列做统计可使用df.describe(includeobject)。大数据集场景下info()和describe()是轻量高效的探索工具。四.特征统计函数1.基础统计函数针对数值型列pandas 提供了常用的聚合统计函数操作后返回标量或 Series函数含义示例代码示例结果sum()求和df_demo.sum()Height: 29869.0, Weight: 10397.0mean()均值df_demo.mean()Height: 163.218033, Weight: 55.015873median()中位数df_demo.median()Height: 161.9, Weight: 51.0var()方差df_demo.var()Height: 74.046, Weight: 164.446std()标准差df_demo.std()Height: 8.608879, Weight: 12.824294max()最大值df_demo.max()Height: 193.9, Weight: 89.0min()最小值df_demo.min()Height: 145.4, Weight: 34.02.进阶统计函数函数含义示例代码示例结果quantile(q)分位数q 为 0~1 之间的数df_demo.quantile(0.75)Height: 167.5, Weight: 65.0count()非缺失值个数df_demo.count()Height: 183, Weight: 189idxmax()最大值对应的索引df_demo.idxmax()Height: 193, Weight: 2idxmin()最小值对应的索引df_demo.idxmin()-3.聚合方向参数axis所有聚合函数都有axis参数用于控制聚合方向axis0默认逐列聚合对每一列计算统计量axis1逐行聚合对每一行计算统计量# 逐行求均值示例身高体重的均值无实际业务意义仅演示语法 df_demo.mean(axis1).head()输出0 102.45 1 118.25 2 138.95 3 41.00 4 124.00 dtype: float64注聚合函数定义操作后返回标量或按列 / 行聚合的 Series因此也叫聚合函数。缺失值处理count()会自动忽略缺失值统计非空样本数量mean()/sum()等也默认忽略缺失值计算。业务场景提示逐行聚合axis1需结合业务逻辑使用比如本数据集中 “身高 体重的均值” 无实际意义仅用于语法演示。快速查看多列统计量df[[Height,Weight]].describe()同时计算多个统计量df_demo.agg([mean,max,count])对不同列应用不同统计量df_demo.agg({Height:mean,Weight:max})五.唯一值操作1.单列组合针对单个 Series列常用函数如下函数作用示例代码示例结果unique()返回所有唯一值组成的数组df[School].unique()[Shanghai Jiao Tong University, Peking University, Fudan University, Tsinghua University]nunique()返回唯一值的个数df[School].nunique()4value_counts()返回唯一值及其出现频次df[School].value_counts()Tsinghua University: 69, Shanghai Jiao Tong University: 57, ...drop_duplicates()去重保留唯一值df[School].drop_duplicates()保留 4 个不同学校名称duplicated()返回布尔序列标记重复行df[School].duplicated().head()[False, False, True, False, True]2.多列组合1drop_duplicates()作用按指定列组合去重保留符合条件的行关键参数keepfirst默认保留每个组合第一次出现的行last保留每个组合最后一次出现的行False剔除所有重复组合只保留出现一次的组合示例# 按 Gender Transfer 组合去重保留第一次出现 df_demo.drop_duplicates([Gender, Transfer]) # 按 Gender Transfer 组合去重保留最后一次出现 df_demo.drop_duplicates([Gender, Transfer], keeplast) # 只保留 Name Gender 组合出现一次的行 df_demo.drop_duplicates([Name, Gender], keepFalse)2duplicated()作用返回布尔序列标记重复行重复为True首次出现为False与drop_duplicates()的关系drop_duplicates()等价于删除duplicated()为True的行示例df_demo.duplicated([Gender, Transfer]).head() # 输出0 False, 1 False, 2 True, 3 True, 4 True3核心区别与联系函数输入输出典型用途unique()Series数组查看类别取值nunique()Series标量统计类别数量value_counts()SeriesSeries统计类别分布drop_duplicates()Series/DataFrameSeries/DataFrame去重、保留唯一组合duplicated()Series/DataFrame布尔 Series标记重复行、筛选重复数据注value_counts()默认按频次降序排列可加sortFalse保持原顺序drop_duplicates()可作用于整个 DataFrame默认按所有列组合去重duplicated()可配合~取反筛选不重复行df[~df.duplicated()]六.替换函数1.映射替换replacereplace是最基础的映射替换方法支持字典或列表两种映射方式写法示例代码说明字典映射df[Gender].replace({Female:0, Male:1})键为原值值为替换后的值列表映射df[Gender].replace([Female,Male], [0,1])两个列表一一对应按顺序替换方向替换method 参数methodffill用前面最近的未被替换值填充methodbfill用后面最近的未被替换值填充s pd.Series([a, 1, b, 2, 1, 1, a]) s.replace([1, 2], methodffill) # 用前面的 a/b 替换 1/2 s.replace([1, 2], methodbfill) # 用后面的 a/b 替换 1/2注正则替换建议使用str.replace当前版本replace对 string 类型正则替换存在 bug。2.逻辑替换wheremaskwhere和mask是完全对称的逻辑替换函数where(condition)条件为 False 的行被替换默认替换为 NaNmask(condition)条件为 True 的行被替换默认替换为 NaN函数示例代码结果说明wheres.where(s0)保留负数非负数变为 NaNwheres.where(s0, 100)保留负数非负数替换为 100masks.mask(s0)负数变为 NaN非负数保留masks.mask(s0, -50)负数替换为 -50非负数保留条件可以是自定义布尔序列只要索引与原 Series 一致即可s_condition pd.Series([True,False,False,True], indexs.index) s.mask(s_condition, -50) # 按自定义布尔序列替换3.数值替换round/abs/clip针对数值型数据的专用替换函数函数作用示例代码结果round(n)四舍五入到 n 位小数s.round(2)1.2345 → 1.23abs()取绝对值s.abs()-1 → 1-50 → 50clip(lower, upper)截断到 [lower, upper] 区间s.clip(0, 2)-1 → 0100 → 24.三类替换函数对比类别核心函数典型场景映射替换replace类别型变量编码如性别→0/1、批量值映射逻辑替换where/mask按条件筛选并替换如异常值修正数值替换round/abs/clip数值精度处理、范围截断、符号转换七.排序函数1.值排序sort_values按数据列的值进行排序支持单列 / 多列排序、升序 / 降序控制。1基础用法单列排序# 按身高升序排序默认 ascendingTrue df_demo.sort_values(Height).head() # 按身高降序排序 df_demo.sort_values(Height, ascendingFalse).head()ascendingTrue默认升序从小到大ascendingFalse降序从大到小2多列排序按多列组合排序需为每一列指定排序方向# 体重升序体重相同时身高降序 df_demo.sort_values( by[Weight, Height], ascending[True, False] ).head()by排序列名列表按列表顺序依次排序ascending布尔列表与by一一对应分别控制每一列的排序方向2.索引排序sort_index按索引行 / 列索引进行排序支持多级索引用法与sort_values完全一致。1基础用法多级索引排序# 按 Grade 升序、Name 降序排序多级索引 df_demo.sort_index( level[Grade, Name], ascending[True, False] ).head()level指定索引层可传索引名或层号ascending布尔列表与level一一对应控制每一层索引的排序方向字符串索引按字母顺序排序3.对比函数排序对象核心参数典型场景sort_values数据列by列名、ascending按数值 / 类别列排序如身高、体重排序sort_index索引level索引层、ascending按行 / 列索引排序如多级索引分类排序注多级索引sort_index可通过level指定索引层实现多级索引的灵活排序排序稳定性pandas 排序默认稳定相同值的行保持原相对顺序缺失值处理sort_values默认将 NaN 放在排序结果末尾可通过na_position调整快速查看排序结果配合.head()预览前几行多列排序时ascending列表长度必须与by列表长度一致索引排序对字符串列按字母顺序如需自定义顺序可使用Categorical八.apply方法apply是 pandas 中用于行 / 列迭代的灵活方法支持传入自定义函数实现对 DataFrame 的列迭代或行迭代。1.核心原理axis参数控制迭代方向与聚合函数完全一致axis0默认列迭代每次传入一列Seriesaxis1行迭代每次传入一行Series传入的函数以 ** 序列Series** 为输入返回标量或序列最终聚合为结果。2.示例1自定义函数实现均值计算df_demo df[[Height, Weight]] # 方式1定义普通函数 def my_mean(x): return x.mean() df_demo.apply(my_mean) # 方式2lambda 表达式简化 df_demo.apply(lambda x: x.mean()) #Height 163.218033 Weight 55.015873 dtype: float642行迭代逐行计算均值df_demo.apply(lambda x: x.mean(), axis1).head() ### 0 102.45 1 118.25 2 138.95 3 41.00 4 124.00 dtype: float64 ###3.自定义统计量madmad平均绝对偏差的计算公式序列中每个元素与均值的绝对偏差的平均值# 用 apply 实现 mad df_demo.apply(lambda x: (x - x.mean()).abs().mean()) # 等价于 pandas 内置 mad 函数 df_demo.mad() # Height 6.707229 Weight 10.391870 dtype: float64 #注性能警告apply自由度高但性能远低于 pandas 内置函数。仅在无内置函数可替代的自定义场景下使用。迭代对象axis0传入列axis1传入行需根据需求选择。lambda 简化简单逻辑优先用 lambda 表达式复杂逻辑用普通函数。九.窗口对象1.滑动窗口rolling1基础用法核心作用对序列按固定窗口大小做滑动计算核心参数window窗口大小axis默认 0列方向s pd.Series([1,2,3,4,5]) roller s.rolling(window3) # 创建窗口大小为3的滑窗对象2 常用聚合计算滑窗对象支持所有聚合函数窗口包含当前行元素函数作用示例结果window3mean()滑动均值[NaN, NaN, 2.0, 3.0, 4.0]sum()滑动求和[NaN, NaN, 6.0, 9.0, 12.0]cov(s2)滑动协方差两序列窗口内协方差corr(s2)滑动相关系数两序列窗口内相关系数3自定义函数apply支持传入自定义函数输入为窗口内的 Series# 等价于 roller.mean() roller.apply(lambda x: x.mean())2.类滑窗函数shift/diff/pct_change这类函数公共参数为periodsn默认 1支持正负 n反方向操作函数作用示例s [1,3,6,10,15]shift(n)取向前第 n 个元素的值shift(2)→[NaN, NaN, 1, 3, 6]diff(n)与向前第 n 个元素做差n 阶差分diff(3)→[NaN, NaN, NaN, 9, 12]pct_change(n)与向前第 n 个元素相比计算增长率pct_change()→[NaN, 2.0, 1.0, 0.666..., 0.5]1反方向操作n 为负shift(-1)取向后第 1 个元素 →[3,6,10,15,NaN]diff(-2)与向后第 2 个元素做差 →[-5, -7, -9, NaN, NaN]2等价滑窗实现类滑窗函数可通过rolling等价实现# shift(2) 等价于 rolling(3) 取窗口第一个元素 s.rolling(3).apply(lambda x: list(x)[0]) # diff(3) 等价于 rolling(4) 取首尾元素差 s.rolling(4).apply(lambda x: list(x)[-1]-list(x)[0]) # pct_change() 等价于 rolling(2) 计算增长率 def my_pct(x): L list(x) return L[-1]/L[0]-1 s.rolling(2).apply(my_pct)3. 扩张窗口累计窗口expanding1核心原理扩张窗口又称累计窗口是动态长度的窗口窗口范围从序列起始位置到当前位置窗口长度随位置逐步扩张示例序列[a1, a2, a3, a4]对应窗口为[a1]、[a1,a2]、[a1,a2,a3]、[a1,a2,a3,a4]本质对序列做累计聚合计算等价于rolling(window当前位置1)的特殊滑动窗口2用法示例s pd.Series([1, 3, 6, 10]) # 创建扩张窗口对象计算累计均值 s.expanding().mean()计算过程拆解位置窗口范围计算结果0[1]1/11.01[1,3](13)/22.02[1,3,6](136)/33.3333333[1,3,6,10](13610)/45.03常用聚合函数扩张窗口支持所有 pandas 聚合函数与rolling完全一致基础统计mean()、sum()、median()、max()、min()离散统计count()、quantile()自定义函数apply(lambda x: ...)注窗口计算规则滑动窗口包含当前行元素如第 4 个位置计算均值为(234)/3而非(123)/3缺失值处理窗口不足时默认返回 NaN性能提示优先使用内置聚合函数apply仅用于自定义场景后续内容日期偏置窗口、指数加权窗口将在后续章节讲解扩张窗口可理解为窗口大小无限扩张的滑动窗口expanding()等价于rolling(windowlen(s), min_periods1)支持axis参数可对 DataFrame 做列 / 行方向的累计聚合