Pandas教学-2
2026/9/15 6:45:06 网站建设 项目流程
# -*- coding: utf-8 -*- """ 案例1:学生成绩统计分析 知识点: 1. pandas 读取 Excel:pd.read_excel() 2. DataFrame 基本分析:求和、求平均、describe() 描述统计 3. 新增列、排序、排名 4. 将多个 DataFrame 写入同一个 Excel 的不同 Sheet(ExcelWriter) 运行后: 在本文件所在目录生成 data 文件夹,里面有 成绩_源数据.xlsx 和 成绩_分析结果.xlsx """ import os import pandas as pd # ---------- 0. 路径准备 ---------- BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 本脚本所在目录 DATA_DIR = os.path.join(BASE_DIR, "data") # 数据文件夹 os.makedirs(DATA_DIR, exist_ok=True) # 不存在则创建 SRC_FILE = os.path.join(DATA_DIR, "成绩_源数据.xlsx") OUT_FILE = os.path.join(DATA_DIR, "成绩_分析结果.xlsx") # ---------- 1. 生成示例 Excel(实际项目中这一步换成你已有的 Excel 文件) ---------- def make_sample(): df = pd.DataFrame({ "学号": [202401, 202402, 202403, 202404, 202405, 202406], "姓名": ["张三", "李四", "王五", "赵六", "钱七", "孙八"], "语文": [85, 76, 92, 60, 78, 88], "数学": [92, 88, 75, 71, 83, 95], "英语": [78, 82, 90, 55, 69, 84], }) df.to_excel(SRC_FILE, sheet_name="成绩表", index=False) print("已生成示例文件:", SRC_FILE) # ---------- 2. 读取 Excel 到 DataFrame ---------- def analyze(): df = pd.read_excel(SRC_FILE, sheet_name="成绩表") print("===== 读取到的原始数据 =====") print(df) # ---------- 3. 数据分析 ---------- # 3.1 每位学生:总分、平均分(只对语文/数学/英语三列计算) subjects = ["语文", "数学", "英语"] df["总分"] = df[subjects].sum(axis=1) # axis=1 表示按行求和 df["平均分"] = df[subjects].mean(axis=1).round(1) # 3.2 按总分降序排名(method="min" 表示同分同名次) df["名次"] = df["总分"].rank(ascending=False, method="min").astype(int) df = df.sort_values("名次") # 按名次排序 # 3.3 全班各科描述统计(平均分、最高分、最低分、标准差等) subject_stat = df[subjects].describe().round(1) # 追加“总分/平均分”两列的统计 subject_stat["总分"] = df["总分"].describe().round(1) subject_stat["平均分"] = df["平均分"].describe().round(1) # 3.4 及格情况:平均分 >= 60 标记为“及格” df["是否及格"] = df["平均分"].apply(lambda x: "及格" if x >= 60 else "不及格") pass_rate = pd.DataFrame({"及格人数": [(df["是否及格"] == "及格").sum()], "不及格人数": [(df["是否及格"] == "不及格").sum()]}) # ---------- 4. 写回 Excel(多个 Sheet 必须在同一个 ExcelWriter 中写入) ---------- with pd.ExcelWriter(OUT_FILE, engine="openpyxl") as writer: df.to_excel(writer, sheet_name="学生排名", index=False) subject_stat.to_excel(writer, sheet_name="各科统计") pass_rate.to_excel(writer, sheet_name="及格情况", index=False) print("\n===== 分析结果(按名次) =====") print(df.to_string(index=False)) print("\n===== 各科描述统计 =====") print(subject_stat) print("\n分析结果已写入:", OUT_FILE) if __name__ == "__main__": make_sample() analyze()
# -*- coding: utf-8 -*- """ 案例2:销售数据分组汇总 知识点: 1. pd.read_excel() 读取销售流水 2. groupby() 分组 + agg() 多种聚合(销售额合计、订单数、平均单价) 3. 分组后排序、占比计算 4. to_excel() 写回 Excel 运行后: 生成 data/销售_源数据.xlsx 和 data/销售_汇总结果.xlsx """ import os import pandas as pd BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_DIR = os.path.join(BASE_DIR, "data") os.makedirs(DATA_DIR, exist_ok=True) SRC_FILE = os.path.join(DATA_DIR, "销售_源数据.xlsx") OUT_FILE = os.path.join(DATA_DIR, "销售_汇总结果.xlsx") # ---------- 1. 生成示例销售流水 ---------- def make_sample(): df = pd.DataFrame({ "订单日期": ["2024-03-01", "2024-03-01", "2024-03-02", "2024-03-02", "2024-03-03", "2024-03-03", "2024-03-04", "2024-03-04"], "地区": ["华北", "华东", "华北", "华南", "华东", "华南", "华北", "华东"], "产品": ["笔记本", "鼠标", "鼠标", "笔记本", "键盘", "鼠标", "键盘", "笔记本"], "数量": [2, 10, 8, 1, 5, 6, 3, 4], "单价": [5000, 50, 50, 5200, 120, 50, 120, 4900], }) df.to_excel(SRC_FILE, sheet_name="销售流水", index=False) print("已生成示例文件:", SRC_FILE) def analyze(): # ---------- 2. 读取数据 ---------- df = pd.read_excel(SRC_FILE, sheet_name="销售流水") # ---------- 3. 派生“销售额”列 ---------- df["销售额"] = df["数量"] * df["单价"] print("===== 带销售额的流水 =====") print(df) # ---------- 4. 按地区分组汇总 ---------- # agg 可同时对不同列做不同聚合;命名格式为 新列名=(原列名, 聚合函数) region_sum = (df.groupby("地区") .agg(销售总额=("销售额", "sum"), 订单数量=("订单日期", "count"), 销售件数=("数量", "sum")) .reset_index()) region_sum = region_sum.sort_values("销售总额", ascending=False) # 计算各地区销售额占比(%% 在字符串里表示一个百分号) region_sum["占比"] = (region_sum["销售总额"] / region_sum["销售总额"].sum() * 100).round(1) # ---------- 5. 按产品分组汇总(平均单价、最高单笔销售额) ---------- product_sum = (df.groupby("产品") .agg(销售总额=("销售额", "sum"), 平均单价=("单价", "mean"), 最高单笔=("销售额", "max")) .reset_index() .round({"平均单价": 1}) .sort_values("销售总额", ascending=False)) # ---------- 6. 按“地区 + 产品”两级分组 ---------- cross_sum = (df.groupby(["地区", "产品"]) .agg(销售额=("销售额", "sum"), 数量=("数量", "sum")) .reset_index()) # ---------- 7. 写回 Excel(多个 Sheet 用同一个 ExcelWriter) ---------- with pd.ExcelWriter(OUT_FILE, engine="openpyxl") as writer: region_sum.to_excel(writer, sheet_name="按地区汇总", index=False) product_sum.to_excel(writer, sheet_name="按产品汇总", index=False) cross_sum.to_excel(writer, sheet_name="地区产品交叉", index=False) print("\n===== 按地区汇总 =====") print(region_sum.to_string(index=False)) print("\n===== 按产品汇总 =====") print(product_sum.to_string(index=False)) print("\n汇总结果已写入:", OUT_FILE) if __name__ == "__main__": make_sample() analyze()
# -*- coding: utf-8 -*- """ 案例3:数据清洗 知识点: 1. 查看数据质量:info()、isnull()、duplicated() 2. 缺失值处理:fillna() 填充、dropna() 删除 3. 重复值处理:drop_duplicates() 4. 列值清洗:strip() 去空格、replace() 统一写法、astype() 类型转换 5. 清洗前后对比写回不同 Sheet 运行后: 生成 data/员工_脏数据.xlsx 和 data/员工_清洗结果.xlsx """ import os import numpy as np import pandas as pd BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_DIR = os.path.join(BASE_DIR, "data") os.makedirs(DATA_DIR, exist_ok=True) SRC_FILE = os.path.join(DATA_DIR, "员工_脏数据.xlsx") OUT_FILE = os.path.join(DATA_DIR, "员工_清洗结果.xlsx") # ---------- 1. 生成一份“脏数据” ---------- def make_sample(): df = pd.DataFrame({ "工号": ["A001", "A002", "A003", "A004", "A005", "A005", "A006"], "姓名": ["张三", " 李四", "王五 ", "赵六", "钱七", "钱七", "孙八"], "部门": ["技术部", "技术部", "市场部", " 市场部", "人事部", "人事部", None], "年龄": [25, 30, np.nan, 28, 35, 35, 40], "工资": ["8000", "9000", "8500", "abc", "12000", "12000", "7600"], }) df.to_excel(SRC_FILE, sheet_name="原始数据", index=False) print("已生成示例文件:", SRC_FILE) def analyze(): # ---------- 2. 读取并体检 ---------- raw = pd.read_excel(SRC_FILE, sheet_name="原始数据") print("===== 原始数据 =====") print(raw) print("\n各列缺失值数量:") print(raw.isnull().sum()) print("重复行数量:", raw.duplicated().sum()) df = raw.copy() # 保留原始数据,用于结果对比 # ---------- 3. 删除完全重复的行 ---------- df = df.drop_duplicates() # ---------- 4. 文本列去空格、统一部门写法 ---------- df["姓名"] = df["姓名"].astype(str).str.strip() df["部门"] = df["部门"].astype(str).str.strip() df["部门"] = df["部门"].replace({"nan": "未分配"}) # None 转成字符串后统一为“未分配” # ---------- 5. 缺失值处理 ---------- # 数值列:用平均年龄填充(fillna 也可填 0 或固定值) df["年龄"] = pd.to_numeric(df["年龄"], errors="coerce") # 先确保是数值 df["年龄"] = df["年龄"].fillna(df["年龄"].mean()).round(0).astype(int) # ---------- 6. 异常值处理:工资列含字母,转不成数字的置为缺失,再用中位数填充 ---------- df["工资"] = pd.to_numeric(df["工资"], errors="coerce") df["工资"] = df["工资"].fillna(df["工资"].median()).astype(int) # ---------- 7. 再次体检 ---------- print("\n===== 清洗后数据 =====") print(df) print("清洗后缺失值数量:", int(df.isnull().sum().sum())) print("清洗后重复行数量:", int(df.duplicated().sum())) # ---------- 8. 写回:原始数据与清洗结果各占一个 Sheet 便于对比 ---------- with pd.ExcelWriter(OUT_FILE, engine="openpyxl") as writer: raw.to_excel(writer, sheet_name="清洗前", index=False) df.to_excel(writer, sheet_name="清洗后", index=False) print("\n清洗结果已写入:", OUT_FILE) if __name__ == "__main__": make_sample() analyze()
# -*- coding: utf-8 -*- """ 案例4:条件筛选与新增计算列 知识点: 1. 布尔索引筛选、query() 条件筛选、isin() 多值筛选 2. apply() / np.where() 按条件新增列 3. 简单分段计算(个税按级距,教学简化版) 4. 将“全量结果”和“筛选结果”分别写入不同 Sheet 运行后: 生成 data/工资_源数据.xlsx 和 data/工资_计算结果.xlsx """ import os import numpy as np import pandas as pd BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_DIR = os.path.join(BASE_DIR, "data") os.makedirs(DATA_DIR, exist_ok=True) SRC_FILE = os.path.join(DATA_DIR, "工资_源数据.xlsx") OUT_FILE = os.path.join(DATA_DIR, "工资_计算结果.xlsx") # 个税起征点(教学简化:不考虑专项附加扣除,按简化级距计算) TAX_THRESHOLD = 5000 # ---------- 1. 生成示例工资数据 ---------- def make_sample(): df = pd.DataFrame({ "工号": ["A001", "A002", "A003", "A004", "A005", "A006", "A007"], "姓名": ["张三", "李四", "王五", "赵六", "钱七", "孙八", "周九"], "部门": ["技术部", "技术部", "市场部", "市场部", "人事部", "财务部", "技术部"], "基本工资": [8000, 15000, 7000, 22000, 9500, 11000, 6000], "绩效奖金": [2000, 5000, 1500, 8000, 2500, 3000, 1000], }) df.to_excel(SRC_FILE, sheet_name="工资表", index=False) print("已生成示例文件:", SRC_FILE) def calc_tax(taxable): """教学简化版个税:按应纳税所得额分三段计税""" if taxable <= 0: return 0 elif taxable <= 3000: return taxable * 0.03 elif taxable <= 12000: return taxable * 0.10 - 210 # 速算扣除数 210 else: return taxable * 0.20 - 1410 # 速算扣除数 1410 def analyze(): # ---------- 2. 读取数据 ---------- df = pd.read_excel(SRC_FILE, sheet_name="工资表") # ---------- 3. 新增计算列 ---------- df["应发工资"] = df["基本工资"] + df["绩效奖金"] df["应纳税所得额"] = (df["应发工资"] - TAX_THRESHOLD).clip(lower=0) # 低于起征点按 0 df["个税"] = df["应纳税所得额"].apply(calc_tax).round(2) df["实发工资"] = df["应发工资"] - df["个税"] # np.where(条件, 满足时的值, 不满足时的值):打工资等级标签 df["工资等级"] = np.where(df["实发工资"] >= 20000, "高薪", np.where(df["实发工资"] >= 10000, "中等", "普通")) # ---------- 4. 条件筛选 ---------- # 方式一:布尔索引——技术部且实发工资大于 10000 tech_high = df[(df["部门"] == "技术部") & (df["实发工资"] > 10000)] # 方式二:query 字符串查询,写法更接近自然语言 mid = df.query("实发工资 >= 8000 and 实发工资 < 20000") # 方式三:isin 多值筛选——人事部或财务部 hr_fin = df[df["部门"].isin(["人事部", "财务部"])] print("===== 工资计算全表 =====") print(df.to_string(index=False)) print("\n===== 技术部实发过万 =====") print(tech_high[["姓名", "部门", "实发工资"]].to_string(index=False)) # ---------- 5. 写回 Excel ---------- with pd.ExcelWriter(OUT_FILE, engine="openpyxl") as writer: df.to_excel(writer, sheet_name="工资全表", index=False) tech_high.to_excel(writer, sheet_name="技术部高薪", index=False) mid.to_excel(writer, sheet_name="中等收入", index=False) hr_fin.to_excel(writer, sheet_name="人事财务", index=False) print("\n计算结果已写入:", OUT_FILE) if __name__ == "__main__": make_sample() analyze()
# -*- coding: utf-8 -*- """ 案例5:多表合并与数据透视表 知识点: 1. 同一 Excel 中读取多个 Sheet(员工信息表 + 销售流水表) 2. pd.merge() 按公共列合并两张表(类似 Excel 的 VLOOKUP) 3. pd.pivot_table() 生成数据透视表(行、列、值、汇总方式、合计行) 4. 多结果写回 Excel 运行后: 生成 data/业务_源数据.xlsx 和 data/业务_分析结果.xlsx """ import os import pandas as pd BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_DIR = os.path.join(BASE_DIR, "data") os.makedirs(DATA_DIR, exist_ok=True) SRC_FILE = os.path.join(DATA_DIR, "业务_源数据.xlsx") OUT_FILE = os.path.join(DATA_DIR, "业务_分析结果.xlsx") # ---------- 1. 生成包含两个 Sheet 的示例工作簿 ---------- def make_sample(): staff = pd.DataFrame({ "工号": ["S01", "S02", "S03", "S04"], "姓名": ["张三", "李四", "王五", "赵六"], "所属部门": ["一部", "一部", "二部", "二部"], }) sales = pd.DataFrame({ "工号": ["S01", "S01", "S02", "S03", "S03", "S04", "S04"], "季度": ["Q1", "Q2", "Q1", "Q1", "Q2", "Q1", "Q2"], "产品": ["A", "A", "B", "A", "B", "A", "B"], "销售额": [12000, 15000, 9000, 20000, 18000, 8000, 11000], }) with pd.ExcelWriter(SRC_FILE, engine="openpyxl") as writer: staff.to_excel(writer, sheet_name="员工信息", index=False) sales.to_excel(writer, sheet_name="销售流水", index=False) print("已生成示例文件:", SRC_FILE) def analyze(): # ---------- 2. 分别读取两个 Sheet ---------- staff = pd.read_excel(SRC_FILE, sheet_name="员工信息") sales = pd.read_excel(SRC_FILE, sheet_name="销售流水") # ---------- 3. merge 合并:把姓名、部门补到销售流水里 ---------- # on 公共列;how="left" 以销售流水为主表,保留全部流水 merged = pd.merge(sales, staff, on="工号", how="left") print("===== 合并后的明细 =====") print(merged.to_string(index=False)) # ---------- 4. 数据透视表:行=姓名,列=季度,值=销售额合计 ---------- pivot_q = pd.pivot_table( merged, index="姓名", # 行 columns="季度", # 列 values="销售额", # 值 aggfunc="sum", # 汇总方式 fill_value=0, # 空值补 0 margins=True, # 添加合计行/列 margins_name="合计", ) # ---------- 5. 数据透视表:行=部门,列=产品,值=销售额均值 ---------- pivot_dp = pd.pivot_table( merged, index="所属部门", columns="产品", values="销售额", aggfunc="mean", fill_value=0, margins=True, margins_name="平均", ).round(0) # ---------- 6. 员工业绩排名表 ---------- rank = (merged.groupby(["姓名", "所属部门"]) .agg(总销售额=("销售额", "sum"), 订单数=("销售额", "count")) .reset_index() .sort_values("总销售额", ascending=False)) # ---------- 7. 写回 Excel ---------- with pd.ExcelWriter(OUT_FILE, engine="openpyxl") as writer: merged.to_excel(writer, sheet_name="合并明细", index=False) pivot_q.to_excel(writer, sheet_name="季度透视表") pivot_dp.to_excel(writer, sheet_name="部门产品透视表") rank.to_excel(writer, sheet_name="业绩排名", index=False) print("\n===== 季度销售额透视表 =====") print(pivot_q) print("\n===== 员工业绩排名 =====") print(rank.to_string(index=False)) print("\n分析结果已写入:", OUT_FILE) if __name__ == "__main__": make_sample() analyze()

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询