✅ DA41 运动会各项目报名透视表
📌 题目描述
- 有两个 CSV 文件:
items.csv:项目信息(item_id,item_name,location)signup.csv:员工报名信息(employee_id,name,sex,department,item_id)
- 要求输出一个透视表 ,展示:
- 行索引:
sex(性别)、department(部门) - 列索引:
item_name(项目名称) - 值:报名人数(统计
employee_id的数量)
- 行索引:
- 不包含没人报名的项目
✅ 代码实现
import pandas as pd
# 读取数据
items = pd.read_csv('items.csv')
signup = pd.read_csv('signup.csv')
# 合并两个表,获取项目名称
merged = pd.merge(signup, items, on='item_id', how='inner')
# 创建透视表
pivot = pd.pivot_table(
merged,
index=['sex', 'department'], # 多级行索引
columns=['item_name'], # 列为项目名
values='employee_id', # 统计员工ID
aggfunc='count', # 聚合方式:计数
fill_value=0 # 缺失值填0
)
print(pivot)
🔍 解析
-
为什么用
merge?- 因为
signup表只有item_id,没有项目名称,必须通过items.csv获取item_name - 使用
inner join自动过滤掉"没人报名"的项目(因为signup中没有对应记录)
- 因为
-
pivot_table参数详解:index: 行分组字段(支持多级)columns: 列分组字段(会变成列名)values: 要聚合的列(这里是employee_id)aggfunc='count': 统计每组中非空的employee_id数量 → 即报名人数fill_value=0: 将 NaN 替换为 0,表格更美观
-
输出示例(示意):
item_name longJump run100m swim50m sex department 男 tech 2 1 0 女 education 1 0 3
⚠️ 常见错误
- 忘记合并表 → 缺少
item_name - 用
outer join→ 可能引入无意义项目 - 不指定
values→ 默认会对所有数值列聚合,导致错误
✅ DA42 合并用户信息表与用户活跃表(简单)
📌 题目描述
- 有两个用户表:
Nowcoder1.csv:用户基本信息(ID, 名字, 等级, 刷题量等)Nowcoder2.csv:用户活跃数据(ID, 签到天数, 提交次数, 最后提交时间)
- 要求通过
Nowcoder_ID合并两张表,输出完整信息
✅ 代码实现
import pandas as pd
# 设置显示选项
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 300)
# 读取数据
df1 = pd.read_csv('Nowcoder1.csv')
df2 = pd.read_csv('Nowcoder2.csv')
# 内连接合并
merged = pd.merge(df1, df2, on='Nowcoder_ID', how='inner')
print(merged)
🔍 解析
-
为什么要用
inner join?- 题目要求"合并输出",隐含意思是只保留两张表都有的用户
- 如果某个用户只在一张表中有数据,可能是异常或未活跃用户,不输出也合理
-
how='inner'vshow='left'?inner: 只保留两表共有的用户left: 保留所有df1的用户,df2没有的字段填 NaN- 本题推荐
inner,因为"完整表格"意味着两部分信息都要有
-
显示设置说明:
max_columns=None: 防止列太多被省略width=300: 让输出更宽,避免换行
✅ DA43 两份用户信息表格中的查找(简单)
📌 题目描述
- 同样是两个用户表(
Nowcoder1.csv,Nowcoder2.csv) - 要求输出:用户名、刷题量、代码提交次数
✅ 代码实现
import pandas as pd
# 设置显示
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 300)
# 读取
df1 = pd.read_csv('Nowcoder1.csv')
df2 = pd.read_csv('Nowcoder2.csv')
# 左连接合并
merged = pd.merge(df1, df2, on='Nowcoder_ID', how='left')
# 提取需要的三列
result = merged[['Name', 'Num_of_exercise', 'Number_of_submissions']]
print(result)
🔍 解析
-
为什么用
left join?- 目标是输出"用户的名字和刷题量"------这些都在
df1中 - "代码提交次数"在
df2中,但不要求每个用户都有 - 所以保留
df1所有用户,df2没有的提交次数显示为NaN或0
- 目标是输出"用户的名字和刷题量"------这些都在
-
与 DA42 的区别:
题目 目的 推荐 howDA42 输出完整用户信息 innerDA43 输出特定字段,允许缺失 left -
列选择技巧:
result = merged[['Name', 'Num_of_exercise', 'Number_of_submissions']]- 使用双层中括号
[[...]]选择多列 - 返回的是 DataFrame,不是 Series
- 使用双层中括号
🧠 扩展知识点总结
1. pd.merge() 的 how 参数对比
| 类型 | 说明 | 使用场景 |
|---|---|---|
inner |
交集:只保留两表都有的键 | 数据完整性要求高 |
left |
左表全保留,右表匹配 | 分析主表 + 补充信息 |
right |
右表全保留 | 较少用 |
outer |
并集:保留所有键 | 全量分析,容忍缺失 |
2. pivot_table 核心参数
| 参数 | 作用 |
|---|---|
index |
行分组字段(可多级) |
columns |
列分组字段(变成列名) |
values |
要聚合的列 |
aggfunc |
聚合函数('count', 'sum', 'mean' 等) |
fill_value |
填充缺失值(如 0) |
3. 读取 CSV 的 sep 问题(回顾)
pd.read_csv('data.csv') # 默认 sep=','(英文逗号)
pd.read_csv('data.tsv', sep='\t') # 制表符分隔必须指定
- ❌ 错误:
sep=','(中文逗号) - ✅ 正确:
sep=','或不写(默认)
✅ 学习建议
-
理解业务逻辑再选
how:- 要不要保留没活跃的用户?→ 决定用
left还是inner
- 要不要保留没活跃的用户?→ 决定用
-
多用
pivot_table做报表 :- 比
groupby + unstack更直观
- 比
-
打印前设置显示选项 :
pd.set_option('display.max_rows', None) pd.set_option('display.max_columns', None) -
先合并再筛选列 :
merge→select columns是标准流程
🎯 总结口诀
"合并看需求,inner 保完整,left 保主表;
透视用 pivot,index 行,columns 列,count 统人数。"