pandas第三方库学习
一、Pandas 简介
Pandas 是 Python 中用于数据处理和分析的核心库,提供了高效、灵活的一维(Series)和二维(DataFrame)数据结构,支持多种数据格式的读写、清洗、转换、分析等操作,是数据科学领域的必备工具。
安装方式:pip install pandas(处理 Excel 需额外安装 pip install openpyxl)
二、核心数据结构
1. Series(一维带标签数组)
- 定义:由数据值(values)和标签(index)组成的一维结构,可存储多种数据类型(整数、字符串、布尔值等)。
- 创建方式:
import pandas as pd# 从列表创建(默认索引为0,1,2...) s1 = pd.Series([1, True, 3.14, "Hello"])# 自定义索引 s2 = pd.Series([1,2,3,4], index=['a','b','c','d'])# 从字典创建(字典的键作为索引,值作为数据) dic = {'name':"张三", "age":18, "height":1.8} s3 = pd.Series(dic)输出: 0 1 1 True 2 3.14 3 Hello dtype: objecta 1 b 2 c 3 d 4 dtype: int64name 张三 age 18 height 1.8 dtype: object - 重要特性:
- 索引对齐:当两个 Series 运算时,会自动按索引对齐(无匹配的位置用 NaN 填充)。
- 支持向量化操作(无需循环,直接对所有元素运算)。
2. DataFrame(二维表格型结构)
- 定义:由行索引(index)、列索引(columns)和数据(values)组成的二维表格,每列可对应不同数据类型(类似 Excel 表格或 SQL 表)。
- 创建方式:
# 从字典创建(键为列名,值为列数据) dic = {'Name': ["张三", "李四", "王五"], "Age": [18, 22, 19]} df1 = pd.DataFrame(dic)# 从列表创建(每个子列表为一行数据,需指定列名) data = [["张三", 18, 1.6], ["李四", 22, 1.8], ["王五", 27, 1.9]] columns = ["Name","Age","Height"] df2 = pd.DataFrame(data, columns=columns)#多个原始列表组合成一个总列表包含字典 books = ["Python编程", "数据分析实战", "机器学习入门", "深度学习", "数据结构与算法"] # 书名 authors = ["张三", "李四", "王五", "赵六", "孙七"] # 作者 publish_years = [2020, 2021, 2022, 2023, 2024] # 出版年份 publishers = ["机械工业出版社", "人民邮电出版社", "清华大学出版社", "电子工业出版社", "高等教育出版社"] # 出版社 prices = [59.8, 69.0, 79.0, 89.0, 49.5] # 定价(元) lst_total=[] for book,author,publish_year,publisher,price in zip(books,authors,publish_years,publishers,prices):dic_item={"book_name":book,"author":author,"publish_year":publish_year,"publisher":publisher,"price":price}lst_total.append(dic_item) print(pd.DataFrame(lst_total))输出:Name Age 0 张三 18 1 李四 22 2 王五 19Name Age Height 0 张三 18 1.6 1 李四 22 1.8 2 王五 27 1.9book_name author publish_year publisher price 0 Python编程 张三 2020 机械工业出版社 59.8 1 数据分析实战 李四 2021 人民邮电出版社 69.0 2 机器学习入门 王五 2022 清华大学出版社 79.0 3 深度学习 赵六 2023 电子工业出版社 89.0 4 数据结构与算法 孙七 2024 高等教育出版社 49.5 - 核心属性:
index:行标签(默认 0,1,2...)columns:列标签(字段名)values:底层数据(二维数组)
三、数据读写(文件操作)
Pandas 支持多种文件格式(CSV、Excel、JSON、SQL 等),以下为常用操作:
1. 读取数据
首先你可以用python来创建相关的文件
import pandas as pd# 准备示例数据
data = {"姓名": ["张三", "李四", "王五", "赵六", "钱七"],"年龄": [18, 19, 17, 20, 18],"性别": ["男", "女", "男", "女", "男"],"学科": ["数学", "语文", "英语", "数学", "语文"],"成绩": [92, 88, 95, 85, 90]
}# 创建DataFrame
df = pd.DataFrame(data)# 保存为Excel文件(需要openpyxl库支持,但不需要导入)
df.to_excel("学生信息.xlsx", sheet_name="学生成绩", index=False, engine="openpyxl")
#index=False 不导出索引数据# 保存为CSV文件
df.to_csv("学生信息.csv", index=False, encoding="utf-8")# 保存为JSON文件
df.to_json("学生信息.json", orient="records", force_ascii=False, indent=2)print("文件生成完成!已创建:")
print("1. 学生信息.xlsx")
print("2. 学生信息.csv")
print("3. 学生信息.json")注意:
orient="records"
主要用于将 “表格型数据”(如 Pandas 的 DataFrame)转换为 JSON 时,定义输出结构:
会把数据按 “行” 拆解,每一行数据生成一个独立的字典(键为列名,值为该行对应列的内容),最终所有字典组成一个列表。
示例:若 DataFrame 有 “姓名”“年龄” 两列,转换后会是 [{"姓名":"张三","年龄":20}, {"姓名":"李四","年龄":25}] 的形式,适合表示多条 “记录”。force_ascii=False
控制非 ASCII 字符(如中文、特殊符号)的编码方式:
默认force_ascii=True时,非 ASCII 字符会被转为 Unicode 转义符(如 “中文”→"\u4e2d\u6587"),确保兼容性但可读性差;
设为False后,非 ASCII 字符会直接以原始字符形式输出(如 “中文” 保留为 “中文”),适合需要直观阅读 JSON 内容的场景(需确保输出目标支持 UTF-8 编码)。indent=2
控制 JSON 输出的 “格式化缩进”:
indent接收整数,代表每一级嵌套的缩进空格数;indent=2即每级缩进 2 个空格,让 JSON 结构按层级换行对齐,大幅提升可读性;
若不设置(默认None),JSON 会是 “紧凑格式”(所有内容挤在一行),适合传输但不便于人工查看。
# 读取 Excel(指定文件名和工作表)
df = pd.read_excel("data.xlsx", sheet_name="Sheet1")# 读取 CSV(默认逗号分隔,可指定分隔符)
df = pd.read_csv("data.csv", sep=",", encoding="utf-8")# 读取 JSON
df = pd.read_json("data.json")
2. 写入数据
# 写入 Excel(index=False 不保留行索引)
df.to_excel("output.xlsx", sheet_name="结果", index=False)# 写入 CSV
df.to_csv("output.csv", index=False, encoding="utf-8")
四、数据查看与基本信息
通过以下方法快速了解数据概况:
| 方法 / 属性 | 说明 |
|---|---|
df.info() | 查看数据类型、非空值数量、内存占用等 |
df.shape | 返回 (行数,列数) |
len(df) | 返回行数 |
df.columns | 列名列表 |
df.index | 行索引列表 |
df.dtypes | 各列数据类型 |
df.size | 总数据量(行数 × 列数) |
df.ndim | 维度(固定为 2) |
df.nunique() | 各列唯一值数量 |
df.describe() | 数值列的统计信息(均值、标准差等) |
df.head(n) | 查看前 n 行(默认 5 行) |
df.tail(n) | 查看后 n 行(默认 5 行) |
补充:df.describe(include='all') 可包含非数值列的统计(如唯一值、频数等)。
五、数据选择与过滤
1. 列选择
# 单个列(返回 Series)
df['成绩']# 多个列(返回 DataFrame)
df[['学生姓名', '学科']]
2. 行选择
loc:按标签(索引 / 列名)选择iloc:按位置(整数索引)选择
# 单行(按标签)
df.loc[0] # 返回第0行(Series,自动转置)# 多行(按标签,包含结束索引)
df.loc[0:3] # 行0到行3# 多行(按位置,不包含结束索引)
df.iloc[0:3] # 行0到行2# 区域选择(行+列)
df.loc[3:10, ['学生姓名', '成绩']] # 行3-10,列'学生姓名'和'成绩'
df.iloc[3:10, 0:2] # 行3-9,前2列
3. 条件过滤
# 单条件:成绩≥90
df[df['成绩'] >= 90]# 多条件(用 &(且)/ |(或),条件需加括号)
df[(df['成绩'] >= 90) & (df['学科'] == "语文")]# query方法(类似SQL查询,更简洁)
df.query("成绩 >= 90 & 学科 == '语文'")
六、数据处理与清洗
1. 缺失值处理
- 检测缺失值:
df.isnull()(返回布尔矩阵)、df.isnull().sum()(各列缺失值数量) - 删除缺失值:
df.dropna(axis=0)(删除含缺失值的行,默认);axis=1删除含缺失值的列 - 填充缺失值:
df.fillna(value)(统一填充);按列自定义填充:df.fillna({'Name': "未知", # 字符串列填充固定值'Age': df['Age'].mean(), # 数值列填充均值'Gender': "未说明" })
2. 重复值处理
- 检测重复值:
df.duplicated()(返回布尔值,标记重复行) - 删除重复值:
# subset:指定判断重复的列;keep:保留'first'(首行)/'last'(末行)/False(全删) df.drop_duplicates(subset=['Name'], keep='last')duplicated说明: 如果某行是重复行(即与之前出现的行完全相同),则对应位置为 True 如果是首次出现的非重复行,则对应位置为 False 默认情况下,该方法会判断所有列的值是否完全相同来确定是否为重复行。可以通过参数 subset 指定特定列来检测重复,例如 df.duplicated(subset=['col1', 'col2']) 只会基于这两列判断重复。 另外,参数 keep 可以控制标记方式: keep='first'(默认):保留首次出现的行,标记后续重复行为 True keep='last':保留最后出现的行,标记之前的重复行为 True keep=False:所有重复行都标记为 True示例代码: import pandas as pd# 构造示例数据(含重复行) data = {'姓名': ['张三', '李四', '张三', '王五', '李四', '张三'],'年龄': [18, 19, 18, 20, 19, 18],'班级': ['一班', '二班', '一班', '三班', '二班', '一班'],'成绩': [90, 85, 90, 95, 85, 92] } df = pd.DataFrame(data) print("原始数据:") print(df) print("-"*50)# 步骤1:用 duplicated() 标记重复行(默认 keep='first',保留第一行,后续重复行标为 True) duplicate_mask = df.duplicated() # 返回布尔 Series print("重复行标记(duplicated() 结果):") print(duplicate_mask) print("-"*50)# 步骤2:用标记筛选出所有重复行(仅查看重复的部分) duplicate_rows = df[duplicate_mask] print("筛选出的重复行(被标记为 True 的行):") print(duplicate_rows) print("-"*50)# 步骤3:用标记手动去重(保留非重复行,等价于 drop_duplicates(keep='first')) # ~ 表示取反:True 变 False,False 变 True unique_rows = df[~duplicate_mask] print("手动去重结果(保留非重复行):") print(unique_rows) print("-"*50)# 步骤4:对比 drop_duplicates() 的结果(与手动去重完全一致) drop_result = df.drop_duplicates(keep='first') print("drop_duplicates() 去重结果:") print(drop_result) print("-"*50)# 扩展:不同参数下的配合(以 keep='last' 为例) duplicate_mask_last = df.duplicated(keep='last') # 保留最后一行,前面的重复行标为 True unique_rows_last = df[~duplicate_mask_last] # 手动去重(保留最后一行) print("keep='last' 时手动去重结果:") print(unique_rows_last) print("drop_duplicates(keep='last') 结果:") print(df.drop_duplicates(keep='last'))
3. 值替换
用 replace 替换特定值(支持单个值、列表、字典):
# 替换单个值
df['成绩'].replace(0, 60) # 把0分替换为60分# 多值替换(列表对应)
df['学科'].replace(['语文', '数学'], ['Chinese', 'Math'])# 按字典替换
df.replace({'性别': {'男': 1, '女': 0}})
4. 异常值处理
通过统计方法检测并处理异常值(如超出 3 倍标准差或 IQR 范围):
# 方法1:标准差法(删除数值列中超出3σ的值)
sigma = df['成绩'].std()
mean = df['成绩'].mean()
df = df[(df['成绩'] >= mean - 3*sigma) & (df['成绩'] <= mean + 3*sigma)]# 方法2:IQR法(四分位距)
Q1 = df['成绩'].quantile(0.25)
Q3 = df['成绩'].quantile(0.75)
IQR = Q3 - Q1
df = df[(df['成绩'] >= Q1 - 1.5*IQR) & (df['成绩'] <= Q3 + 1.5*IQR)]
七、数据转换与操作
1. 数据类型转换
用 astype 转换列的数据类型:
df['年龄'] = df['年龄'].astype(int) # 转为整数
df['日期'] = df['日期'].astype('datetime64') # 转为日期类型
df['类别'] = df['类别'].astype('category') # 转为类别型(节省内存)
2. 索引操作
- 重置索引:
df.reset_index(drop=True)(drop=True 丢弃原索引) - 设置索引:
df.set_index('学生姓名')(用某列作为新索引) - 重新索引:
df.reindex(['a','b','c'])(按新索引重新排列,无匹配则为 NaN)
import pandas as pd# 1. 构造原始数据(默认索引为0,1,2,3)
data = {'姓名': ['张三', '李四', '王五', '赵六'],'年龄': [18, 19, 17, 20],'班级': ['一班', '二班', '一班', '三班']
}
df = pd.DataFrame(data)
print("="*50)
print("1. 原始数据(默认整数索引):")
print(df)
print("原始索引:", df.index.tolist()) # 查看索引# 2. 重置索引(reset_index):重新生成默认整数索引
# 先模拟索引被打乱的场景(比如筛选部分行后索引不连续)
df_filtered = df[df['班级'] == '一班'] # 筛选出“一班”的学生,此时索引为[0,2]
print("\n" + "="*50)
print("2.1 筛选后的索引(不连续):")
print(df_filtered)
print("筛选后索引:", df_filtered.index.tolist())# 重置索引(drop=True:丢弃原索引,不保留为新列)
df_reset = df_filtered.reset_index(drop=True)
print("\n2.2 重置索引后(drop=True):")
print(df_reset)
print("重置后索引:", df_reset.index.tolist()) # 索引变为[0,1]# 对比:drop=False(保留原索引为新列)
df_reset_keep = df_filtered.reset_index(drop=False)
print("\n2.3 重置索引后(drop=False):")
print(df_reset_keep) # 新增“index”列保存原索引# 3. 设置索引(set_index):用某列作为新索引
df_set = df.set_index('姓名') # 用“姓名”列替换默认索引
print("\n" + "="*50)
print("3. 设置索引后(以“姓名”为索引):")
print(df_set)
print("新索引:", df_set.index.tolist()) # 索引变为['张三','李四','王五','赵六']# 可以通过新索引访问数据(例如按姓名查行)
print("\n通过新索引访问行(张三):")
print(df_set.loc['张三'])# 4. 重新索引(reindex):按新索引列表重新排列行,无匹配则填充NaN
# 基于上面“以姓名为索引”的df_set,定义新的索引列表
new_index = ['张三', '王五', '孙七'] # 包含原索引(张三、王五)和新索引(孙七)
df_reindex = df_set.reindex(new_index)
print("\n" + "="*50)
print("4. 重新索引后(按['张三','王五','孙七']排列):")
print(df_reindex)
print("重新索引后的索引:", df_reindex.index.tolist())
# 解释:“孙七”不在原索引中,对应行填充NaN运行结果
==================================================
1. 原始数据(默认整数索引):姓名 年龄 班级
0 张三 18 一班
1 李四 19 二班
2 王五 17 一班
3 赵六 20 三班
原始索引: [0, 1, 2, 3]==================================================
2.1 筛选后的索引(不连续):姓名 年龄 班级
0 张三 18 一班
2 王五 17 一班
筛选后索引: [0, 2]2.2 重置索引后(drop=True):姓名 年龄 班级
0 张三 18 一班
1 王五 17 一班
重置后索引: [0, 1]2.3 重置索引后(drop=False):index 姓名 年龄 班级
0 0 张三 18 一班
1 2 王五 17 一班==================================================
3. 设置索引后(以“姓名”为索引):年龄 班级
姓名
张三 18 一班
李四 19 二班
王五 17 一班
赵六 20 三班
新索引: ['张三', '李四', '王五', '赵六']通过新索引访问行(张三):
年龄 18
班级 一班
Name: 张三, dtype: object==================================================
4. 重新索引后(按['张三','王五','孙七']排列):年龄 班级
姓名
张三 18.0 一班
王五 17.0 一班
孙七 NaN NaN
重新索引后的索引: ['张三', '王五', '孙七']3. 行 / 列删除
用 drop 删除指定行或列:
df.drop([0, 1], axis=0) # 删除行0和行1
df.drop(['无用列'], axis=1) # 删除列'无用列'示例代码:
import pandas as pd# 1. 构造原始数据(5行5列,包含一个“无用列”)
data = {'姓名': ['张三', '李四', '王五', '赵六', '钱七'],'年龄': [18, 19, 17, 20, 18],'班级': ['一班', '二班', '一班', '三班', '二班'],'成绩': [90, 85, 95, 88, 92],'无用列': ['a', 'b', 'c', 'd', 'e'] # 用于演示删除的列
}
df = pd.DataFrame(data)
print("="*50)
print("1. 原始数据:")
print(df)
print("原始行数:", len(df), ",原始列数:", len(df.columns))# 2. 删除行(axis=0,默认值,可省略)
# 删除索引为0和1的行(即“张三”和“李四”所在行)
df_drop_rows = df.drop([0, 1], axis=0) # axis=0 表示删除行
print("\n" + "="*50)
print("2. 删除行0和行1后:")
print(df_drop_rows)
print("删除后行数:", len(df_drop_rows), ",列数不变:", len(df_drop_rows.columns))# 3. 删除列(axis=1)
# 删除列名为“无用列”的列
df_drop_col = df.drop(['无用列'], axis=1) # axis=1 表示删除列
print("\n" + "="*50)
print("3. 删除列'无用列'后:")
print(df_drop_col)
print("行数不变:", len(df_drop_col), ",删除后列数:", len(df_drop_col.columns))# 4. 扩展:直接修改原数据(inplace=True)
df_copy = df.copy() # 复制原数据避免修改原始df
df_copy.drop([0], axis=0, inplace=True) # 直接删除原数据的行0
df_copy.drop(['年龄'], axis=1, inplace=True) # 直接删除原数据的“年龄”列
print("\n" + "="*50)
print("4. 用inplace=True直接修改原数据后:")
print(df_copy)输出:
==================================================
1. 原始数据:姓名 年龄 班级 成绩 无用列
0 张三 18 一班 90 a
1 李四 19 二班 85 b
2 王五 17 一班 95 c
3 赵六 20 三班 88 d
4 钱七 18 二班 92 e
原始行数: 5 ,原始列数: 5==================================================
2. 删除行0和行1后:姓名 年龄 班级 成绩 无用列
2 王五 17 一班 95 c
3 赵六 20 三班 88 d
4 钱七 18 二班 92 e
删除后行数: 3 ,列数不变: 5==================================================
3. 删除列'无用列'后:姓名 年龄 班级 成绩
0 张三 18 一班 90
1 李四 19 二班 85
2 王五 17 一班 95
3 赵六 20 三班 88
4 钱七 18 二班 92
行数不变: 5 ,删除后列数: 4==================================================
4. 用inplace=True直接修改原数据后:姓名 班级 成绩 无用列
1 李四 二班 85 b
2 王五 一班 95 c
3 赵六 三班 88 d
4 钱七 二班 92 e4. 应用函数
map:用于 Series,对每个元素应用函数apply:用于 DataFrame,对行 / 列应用函数(默认列方向,axis=1为行方向)applymap:用于 DataFrame,对每个元素应用函数(Python 3.9+ 推荐用df.transform(lambda x: ...)替代)
# 对成绩列加5分
df['成绩'] = df['成绩'].map(lambda x: x + 5 if x <= 95 else 100)# 对每行计算年龄+成绩的和(行方向)
df['年龄+成绩'] = df.apply(lambda row: row['Age'] + row['成绩'], axis=1)示例代码:
import pandas as pd# 1. 构造原始数据
data = {'姓名': ['张三', '李四', '王五', '赵六'],'年龄': [18, 19, 17, 20],'成绩': [85, 76, 92, 68],'班级': ['一班', '二班', '一班', '三班']
}
df = pd.DataFrame(data)
print("="*60)
print("原始数据:")
print(df)# 2. map:对Series(单列)的每个元素应用函数
# 场景1:将成绩转换为等级(A/B/C/D)
def score_to_level(score):if score >= 90:return 'A'elif score >= 80:return 'B'elif score >= 70:return 'C'else:return 'D'
df['等级'] = df['成绩'].map(score_to_level)# 场景2:用字典映射替换班级名称(一班→1班,二班→2班...)
class_map = {'一班': '1班', '二班': '2班', '三班': '3班'}
df['班级_简写'] = df['班级'].map(class_map)print("\n" + "="*60)
print("2. 用map处理后(成绩转等级+班级简写):")
print(df)# 3. apply:对DataFrame的行/列应用函数
# 场景1:axis=0(默认)→ 对列应用函数(计算列的范围:max-min)
def calc_range(column):return column.max() - column.min()
col_range = df[['年龄', '成绩']].apply(calc_range, axis=0)print("\n" + "="*60)
print("3.1 apply(axis=0)计算列的范围(max-min):")
print(col_range)# 场景2:axis=1 → 对行应用函数(判断是否为优秀学员:年龄≤18且成绩≥85)
def is_excellent(row):return '是' if (row['年龄'] <= 18 and row['成绩'] >= 85) else '否'
df['优秀学员'] = df.apply(is_excellent, axis=1)print("\n3.2 apply(axis=1)每行判断优秀学员后:")
print(df)# 4. applymap:对DataFrame所有元素应用函数(字符串转大写+数值加10) 被弃用
# def process_element(x):
# if isinstance(x, str): # 字符串转大写(中文无变化)
# return x.upper()
# elif isinstance(x, int): # 整数加10
# return x + 10
# return x # 其他类型不变
# df_applymap = df.applymap(process_element)
#
# print("\n" + "="*60)
# print("4. applymap处理所有元素后(字符串大写+数值+10):")
# print(df_applymap)# 5. transform:替代applymap处理数值列(更高效,对年龄和成绩加5)
df[['年龄', '成绩']] = df[['年龄', '成绩']].transform(lambda x: x + 5)print("\n" + "="*60)
print("5. transform对数值列(年龄、成绩)加5后:")
print(df)输出:
============================================================
原始数据:姓名 年龄 成绩 班级
0 张三 18 85 一班
1 李四 19 76 二班
2 王五 17 92 一班
3 赵六 20 68 三班============================================================
2. 用map处理后(成绩转等级+班级简写):姓名 年龄 成绩 班级 等级 班级_简写
0 张三 18 85 一班 B 1班
1 李四 19 76 二班 C 2班
2 王五 17 92 一班 A 1班
3 赵六 20 68 三班 D 3班============================================================
3.1 apply(axis=0)计算列的范围(max-min):
年龄 3
成绩 24
dtype: int643.2 apply(axis=1)每行判断优秀学员后:姓名 年龄 成绩 班级 等级 班级_简写 优秀学员
0 张三 18 85 一班 B 1班 是
1 李四 19 76 二班 C 2班 否
2 王五 17 92 一班 A 1班 是
3 赵六 20 68 三班 D 3班 否============================================================
5. transform对数值列(年龄、成绩)加5后:姓名 年龄 成绩 班级 等级 班级_简写 优秀学员
0 张三 23 90 一班 B 1班 是
1 李四 24 81 二班 C 2班 否
2 王五 22 97 一班 A 1班 是
3 赵六 25 73 三班 D 3班 否
5. 字符串处理
通过 .str 访问字符串方法(仅对 object 或 string 类型列有效):
df['姓名'] = df['姓名'].str.strip() # 去除首尾空格
df['姓名'] = df['姓名'].str.upper() # 转为大写
df[df['地址'].str.contains('北京')] # 筛选包含'北京'的行
6. 日期时间处理
- 用
pd.to_datetime转换字符串为日期:df['日期'] = pd.to_datetime(df['日期字符串'], format='%Y-%m-%d') - 提取日期信息:
df['年份'] = df['日期'].dt.year df['月份'] = df['日期'].dt.month
八、数据分组与聚合
按一个或多个列分组,对每组应用聚合函数(如均值、计数等)。
1. 基本分组
# 按'学科'分组
grouped = df.groupby('学科')# 遍历分组
for group_name, group_data in grouped:print(f"分组:{group_name}")print(group_data)
2. 聚合操作
# 按学科分组,计算每组成绩的均值、计数、最大值
grouped = df.groupby('学科')['成绩']
print(grouped.mean()) # 均值
print(grouped.count()) # 数量
print(grouped.max()) # 最大值# 多聚合函数(用 agg)
grouped.agg(['mean', 'max', 'min'])
3. 分组转换(transform)
返回与原数据同形状的结果(常用于组内标准化等):
# 按学科计算成绩的组内均值,并替换原成绩
df['组内均值'] = df.groupby('学科')['成绩'].transform('mean')
九、数据合并与连接
1. merge(按列连接,类似 SQL join)
pd.merge(df1, df2, on='key', how='inner') # 内连接(默认)
pd.merge(df1, df2, on='key', how='left') # 左连接
pd.merge(df1, df2, on='key', how='right') # 右连接
pd.merge(df1, df2, on='key', how='outer') # 外连接
2. join(按索引连接,默认左连接)
df1.join(df2, how='inner') # 按索引内连接
3. concat(沿轴拼接,行 / 列方向)
pd.concat([df1, df2], axis=0) # 行方向拼接(默认)
pd.concat([df1, df2], axis=1) # 列方向拼接
十、数据排序
1. 按索引排序
df.sort_index(ascending=True) # 升序(默认);ascending=False 降序
2. 按值排序
# 按单列排序
df.sort_values(by='成绩', ascending=False) # 成绩降序# 按多列排序(先按Age升序,再按Score降序)
df.sort_values(by=['Age', 'Score'], ascending=[True, False])
十一、数据透视表(pivot_table)
类似 Excel 数据透视表,用于多维度聚合分析:
# index:行分组;columns:列分组;values:聚合列;aggfunc:聚合函数
pd.pivot_table(df,index='学科', # 行:按学科分组columns='班级', # 列:按班级分组values='成绩', # 聚合数据:成绩aggfunc='mean' # 聚合函数:均值
)
十二、Pandas 与 NumPy 的区别
| 维度 | NumPy | Pandas |
|---|---|---|
| 核心结构 | ndarray(多维数组,同数据类型) | Series(一维带标签)、DataFrame(二维表格,异数据类型) |
| 索引机制 | 仅整数索引 | 显式标签索引(支持字符串、日期等) |
| 功能侧重 | 数值计算(矩阵运算、傅里叶变换等) | 数据处理与分析(清洗、分组、合并等) |
| 数据类型 | 单一数据类型 | 每列可不同数据类型(数值、字符串、日期等) |
| 适用场景 | 科学计算、机器学习底层运算 | 数据分析、数据清洗、业务报表等 |
