Python 玩转 Excel 案例【第 13 期】
📌 案例说明
原始数据表:
这是包含5个部门、共50条销售记录的原始数据表,只有姓名、部门、销售额三列。
目标任务:
在日常工作中,我们经常需要对销售数据进行排名分析。不仅要计算公司整体排名,还要计算部门内部排名,并给前三名打上奖牌标记。
本期案例将跟大家学习如何用 Python 自动完成这些操作,让排名结果一目了然:
核心操作:排名计算 + 奖牌标记
- • 关键函数:
rank()、apply()、groupby()
📜 完整代码
"""
销售业绩排名工具
功能:计算排名、标记奖牌
"""
import pandas as pd
# ========== 参数配置 ==========
file_path = "销售业绩表.xlsx"
output_file = "销售业绩排名.xlsx"
# ========== 读取数据 ==========
df = pd.read_excel(file_path)
print(f"📊 共读取 {len(df)} 条销售记录")
print(f" 涉及部门:{df['部门'].nunique()} 个")
# ========== 计算排名 ==========
# 公司排名(按销售额降序,相同销售额并列)
df["公司排名"] = df["销售额"].rank(method="min", ascending=False).astype(int)
# 部门排名
df["部门排名"] = df.groupby("部门")["销售额"].rank(method="min", ascending=False).astype(int)
print(f"\n🏆 排名计算完成")
print(f" 最高销售额:{df['销售额'].max():,.0f}")
print(f" 公司第1名:{df[df['公司排名']==1]['姓名'].values[0]}")
# ========== 标记奖牌 ==========
def get_medal(rank):
if rank == 1:
return "🥇 金牌"
elif rank == 2:
return "🥈 银牌"
elif rank == 3:
return "🥉 铜牌"
else:
return ""
df["奖牌"] = df["公司排名"].apply(get_medal)
# ========== 显示前3名 ==========
top3_df = df.sort_values("公司排名").head(3)
print(f"\n🏆 排名前3:")
print(top3_df[["姓名", "部门", "销售额", "奖牌"]].to_string(index=False))
# ========== 保存到 Excel ==========
df.to_excel(output_file, index=False)
print(f"\n✅ 结果已保存:{output_file}")
第一步:导入所需库
import pandas as pd
代码解释:
- •
import pandas as pd
导入 pandas 库,这是 Python 数据处理的核心工具。它提供了 read_excel() 读取 Excel 文件、DataFrame 数据结构、rank() 计算排名等强大功能。
第二步:参数配置
file_path = "销售业绩表.xlsx"
output_file = "销售业绩排名.xlsx"
代码解释:
- •
file_path
源文件路径,程序从这里读取原始销售数据。可以根据实际情况修改文件名或路径。 - •
output_file
输出文件路径,处理后的结果保存到这里。为了避免覆盖原文件,建议使用不同的文件名。
💡 小贴士:将参数放在代码开头,方便后续修改和维护,也便于他人理解和使用你的代码。
第三步:读取数据
df = pd.read_excel(file_path)
print(f"📊 共读取 {len(df)} 条销售记录")
print(f" 涉及部门:{df['部门'].nunique()} 个")
代码解释:
- •
pd.read_excel(file_path)
读取 Excel 文件并返回一个 DataFrame 对象。 - •
len(df)
获取 DataFrame 的行数,即销售记录总数。本例中原始数据有 50 条记录。 - •
df['部门'].nunique()
nunique() 方法返回指定列中唯一值的数量。这里统计有多少个不同的部门,结果为 5 个。
⚠️ 重要提示:
这里用的是 nunique() 而不是 unique(),两者功能不同:
- •
df['部门'].nunique():返回唯一值的个数(整数类型)。例如本例中结果为 5,表示有5个不同的部门。 - •
df['部门'].unique():返回唯一值的列表(数组类型)。例如本例中结果为 ['销售一部', '销售二部', '销售三部', '销售四部', '销售五部'],可以看到具体有哪些部门。
使用场景区分:
- • 如果想统计有多少个部门,用
nunique()
输出示例:
📊 共读取 50 条销售记录
涉及部门:5 个
第四步:计算排名
# ========== 计算排名 ==========
# 公司排名(按销售额降序,相同销售额并列)
df["公司排名"] = df["销售额"].rank(method="min", ascending=False).astype(int)
# 部门排名
df["部门排名"] = df.groupby("部门")["销售额"].rank(method="min", ascending=False).astype(int)
rank() 函数详解
rank() 是 pandas 中专门用于计算排名的函数,它有多个参数可以灵活控制排名规则。
参数解析
rank() 函数有两个核心参数:
- •
method="min":指定并列排名的处理方式 - • 例如:销售额为 100、100、90 的三个人,排名结果为 1、1、3(跳过第2名)
method 参数详解
为什么选择 method="min"?
在销售排名中,如果两个人销售额相同,应该并列同一名次,且下一个名次要跳过(比如:1,1,3)。"min" 方法正好满足这个需求。
公司排名代码详解
df["公司排名"] = df["销售额"].rank(method="min", ascending=False).astype(int)
- •
.rank(method="min", ascending=False):计算排名,降序排列 - •
.astype(int):将排名结果转换为整数类型(默认是浮点数)
执行过程示意:
原始销售额:199503, 196867, 191699, 187337, ...
↓ rank(method="min", ascending=False)
排名结果: 1, 2, 3, 4, ...
部门排名代码详解
df["部门排名"] = df.groupby("部门")["销售额"].rank(method="min", ascending=False).astype(int)
- •
.rank(...):在每个部门内部独立计算排名
执行过程示意(部门内部):
销售一部数据:
销售额:196867, 187337, 181932, 171958, ...
↓ 部门内排名
排名: 1, 2, 3, 4, ...
销售二部数据:
销售额:176324, 153355, 117221, 114925, ...
↓ 部门内排名
排名: 1, 2, 3, 4, ...
第五步:标记奖牌
# ========== 标记奖牌 ==========
def get_medal(rank):
if rank == 1:
return "🥇 金牌"
elif rank == 2:
return "🥈 银牌"
elif rank == 3:
return "🥉 铜牌"
else:
return ""
df["奖牌"] = df["公司排名"].apply(get_medal)
5.1 知识点:apply() 函数详解
apply() :对 DataFrame 或 Series 的每个元素应用自定义函数。
函数定义
def get_medal(rank):
if rank == 1:
return "🥇 金牌"
elif rank == 2:
return "🥈 银牌"
elif rank == 3:
return "🥉 铜牌"
else:
return ""
- • 输入参数:
rank 是公司排名的数值(1,2,3...) - • 返回值:根据排名返回对应的奖牌字符串,非前三名返回空字符串
- • 使用表情符号:🥇、🥈、🥉 让奖牌更直观,在 Excel 中也显示良好
apply() 的应用
df["奖牌"] = df["公司排名"].apply(get_medal)
- •
df["公司排名"]:选择公司排名列(一个 Series) - •
.apply(get_medal):对排名列的每个值调用 get_medal 函数
执行过程示意:
公司排名 → get_medal() → 奖牌
1 → 🥇 金牌
2 → 🥈 银牌
3 → 🥉 铜牌
4 →
5 →
...
💡 小贴士:apply() 不仅可以用自定义函数,还可以用 lambda 表达式简化代码:
df["奖牌"] = df["公司排名"].apply(
lambda x: "🥇 金牌" if x==1 else "🥈 银牌" if x==2 else "🥉 铜牌" if x==3 else ""
)
第六步:显示前3名
# ========== 显示前3名 ==========
top3_df = df.sort_values("公司排名").head(3)
print(f"\n🏆 排名前3:")
print(top3_df[["姓名", "部门", "销售额", "奖牌"]].to_string(index=False))
6.1 代码详解
df.sort_values("公司排名")
- • 默认:升序排列(排名1、2、3...排在前面)
- • 注意:这里不需要
ascending=True,因为默认就是升序
.head(3)
- • 返回值:一个新的 DataFrame,包含前3名数据
.to_string(index=False)
- • 作用:将 DataFrame 转换为字符串格式打印
- •
index=False:不显示行索引,让输出更整洁
输出示例:
🏆 排名前3:
姓名 部门 销售额 奖牌
销售三部_5号 销售三部 199503 🥇 金牌
销售一部_2号 销售一部 196867 🥈 银牌
销售五部_3号 销售五部 191699 🥉 铜牌
第七步:保存结果
# ========== 保存到 Excel ==========
df.to_excel(output_file, index=False)
print(f"\n✅ 结果已保存:{output_file}")
7.1 to_excel() 参数详解
输出示例:
✅ 结果已保存:销售业绩排名.xlsx
运行结果预览
生成的 销售业绩排名.xlsx 内容如下(部分展示):
效果特点:
📚 本期核心知识点
📍 知识点 1:rank() 函数计算排名
# 公司排名(降序,并列取最小排名)
df["公司排名"] = df["销售额"].rank(method="min", ascending=False).astype(int)
# 部门排名(分组后独立排名)
df["部门排名"] = df.groupby("部门")["销售额"].rank(method="min", ascending=False).astype(int)
- •
method 参数控制并列排名规则(min、max、average、dense、first)
📍 知识点 2:apply() 应用自定义函数
def get_medal(rank):
if rank == 1:
return "🥇 金牌"
elif rank == 2:
return "🥈 银牌"
elif rank == 3:
return "🥉 铜牌"
else:
return ""
df["奖牌"] = df["公司排名"].apply(get_medal)
- • 可以处理复杂逻辑,比简单的
map() 更灵活
📍 知识点 3:groupby() 分组操作
df.groupby("部门")["销售额"].rank(...)
📍 知识点 4:nunique() 统计唯一值数量
df['部门'].nunique() # 统计有多少个不同的部门
- • 比
len(df['部门'].unique()) 更简洁
📍 知识点 5:sort_values() + head() 获取前N名
top3_df = df.sort_values("公司排名").head(3)
📍 知识点 6:to_string() 美化打印
print(top3_df[["姓名", "部门", "销售额", "奖牌"]].to_string(index=False))
🔄 本案例核心流程
① 读取数据 → ② 计算公司排名 → ③ 计算部门排名 → ④ 标记奖牌 → ⑤ 显示前3名 → ⑥ 保存结果
读取原始数据 (pd.read_excel)
↓
显示数据概览 (len, nunique)
↓
计算公司排名 (df["销售额"].rank())
↓
计算部门排名 (df.groupby("部门")["销售额"].rank())
↓
标记奖牌 (df["公司排名"].apply(get_medal))
↓
显示前3名 (sort_values + head + to_string)
↓
保存结果 (df.to_excel)
📦 资源获取提示
关注「码农自习室」,后台回复关键词 PythonExcel案例,即可获取本文完整代码及配套练习数据集,一起动手掌握高效数据操作的核心技巧!
❤️ 支持我们
如果本文对你有帮助,欢迎点赞 + 关注 + 点亮小红心,你的支持就是我们持续创作的最大动力~