数据分析:合并

发布于:2025-09-12 ⋅ 阅读:(28) ⋅ 点赞:(0)

🔷 DA37:统计运动会项目报名人数(仅输出有人报名的项目)

✅ 题目描述

给定两个 CSV 文件:

  • items.csv:包含项目信息(item_id, item_name, location)
  • signup.csv:包含员工报名信息(employee_id, name, sex, department, item_id)

要求:统计每个项目的报名人数,只输出报名人数不为 0 的项目。

💡 即:只要有人报了的项目才显示。


✅ 正确代码

import pandas as pd

df_items = pd.read_csv('items.csv', sep=',')
df_signup = pd.read_csv('signup.csv', sep=',')

# 内连接合并,自动过滤没有报名记录的项目
df_merge = pd.merge(df_items, df_signup, on='item_id')

# 按项目名称分组,统计 employee_id 的数量
result = df_merge.groupby('item_name')['employee_id'].size()

print(result)

🔍 代码解析

解释
pd.merge(..., on='item_id') 使用 item_id 作为键进行内连接(默认),只有在两个表中都存在的项目才会保留 → 自动排除无人报名的项目
.groupby('item_name') 按“项目名称”分组
['employee_id'].size() 统计每组中有多少条记录(即报名人数)<br>⚠️ 注意:size() 包括 NaN 值;若用 count() 则会跳过 NaN(更安全)
print(result) 输出 Series:索引是项目名,值是人数

✅ 特点:使用 inner join(默认),天然只保留有报名数据的项目。


🧠 扩展知识

知识点 说明
merge() 默认行为 不指定 how 时,默认为 'inner',即只保留两表共有的 key
groupby().size() vs .count() <ul><li>size():返回每组总行数,包括 NaN</li><li>count():对各列统计非空值个数</li></ul>在此场景下两者等价(employee_id 不为空)
输出格式 返回的是一个 Series,打印时自动省略列名,符合题目要求

🔷 DA38:统计运动会项目报名人数(二)—— 包含无人报名的项目

✅ 题目描述

同上,但这次要求:

输出 items.csv 中所有项目的报名人数,即使没人报名也显示为 0。


✅ 正确代码

import pandas as pd

df_items = pd.read_csv('items.csv', sep=',')
df_signup = pd.read_csv('signup.csv', sep=',')

# 左连接:以 items 为主表,保留所有项目
df_merge = pd.merge(df_items, df_signup, on='item_id', how='left')

# 分组并使用 count 统计非空 employee_id 数量
result = df_merge.groupby('item_name')['employee_id'].count()

print(result)

🔍 代码解析

关键点 解释
how='left' 左连接,确保 df_items 中的所有项目都被保留<br>→ 即使没人报名,也会出现在结果中,employee_id 为 NaN
.count() 只统计非 NaN 的值 → 无人报名则为 0
groupby('item_name') 按项目名聚合
print(result) 输出所有项目及其报名人数(含 0)

✅ 核心思想:主表驱动 + left join + count 处理缺失值


🧠 扩展知识

技巧 应用场景
left join 主表完整、从表补充信息的经典模式(如商品+销量)
fillna(0) 如果你想显式补零:df_merge['employee_id'].fillna(0)
reindex() 若想确保所有项目按 items.csv 顺序出现,可用 reindex

🔷 DA39:多报名表的运动项目人数统计

✅ 题目描述

新增一个文件 signup1.csv,是另一个部门的报名数据。 要求:将 signup.csvsignup1.csv 合并后,再统计各项目的报名人数(只输出有人报名的)。


✅ 正确代码

import pandas as pd

item = pd.read_csv("items.csv", sep=",")
sign = pd.read_csv("signup.csv", sep=",")
sign1 = pd.read_csv("signup1.csv", sep=",")

# 上下拼接两个报名表
sign_m = pd.concat([sign, sign1], axis=0)

# 与项目表内连接
m = pd.merge(sign_m, item, how="inner", on="item_id")

# 按项目名分组,统计员工数量
print(m.groupby("item_name")["employee_id"].count())

🔍 代码解析

步骤 说明
pd.concat([sign, sign1], axis=0) 将两个报名表纵向堆叠(union),合并成一张大报名表
axis=0 沿行方向拼接(上下接)
merge(..., how='inner') 只保留存在于 items.csv 中的项目(防止无效 item_id)
groupby().count() 统计每个项目的总报名人数(来自两个文件)

✅ 重点:先合并报名数据,再关联项目信息。


🧠 扩展知识

方法 用途
pd.concat([...], ignore_index=True) 重置行索引,避免重复 index
append() 已弃用 推荐使用 concat 替代
去重处理 若担心重复报名:sign_m.drop_duplicates(subset=['employee_id', 'item_id'])

🔷 DA40:统计职能部门中报名标枪的员工信息

✅ 题目描述

找出 职能部门(functional) 中报名了 标枪(javelin) 的所有员工,并输出他们的:

  • employee_id
  • name
  • sex

⚠️ 注意:结果要重置索引(从 0 开始连续编号)


✅ 正确代码

import pandas as pd 

df1 = pd.read_csv("items.csv", sep=',')
df2 = pd.read_csv("signup.csv", sep=',')

# 先合并项目和报名信息
df = pd.merge(df1, df2, on='item_id')

# 筛选条件:部门是 functional,项目是 javelin
df_fun = df[(df.department == 'functional') & (df.item_name == "javelin")]

# 选择指定列并重置索引
result = df_fun[["employee_id", "name", "sex"]].reset_index(drop=True)

print(result)

🔍 代码解析

步骤 说明
pd.merge(..., on='item_id') 获取每个报名记录对应的项目名称
(df.A == X) & (df.B == Y) 多条件筛选,注意括号和 &(不能用 and
df[[...]] 选取特定列
.reset_index(drop=True) 重新生成从 0 开始的整数索引,丢弃原索引

✅ 输出是一个 DataFrame,结构清晰。


🧠 扩展知识

技术点 提示
条件逻辑运算符 <ul><li>&:且</li><li>&#124;:或</li><li>~:非</li></ul>必须加括号!
字符串匹配 若不确定拼写可用:<br>df.item_name.str.contains('javelin', case=False)
query() 方法 更简洁的筛选方式:<br>df.query("department == 'functional' and item_name == 'javelin'")
drop=True 避免旧索引变成新列

📚 总结对比表(四题核心差异)

题号 目标 关键操作 连接方式 聚合/筛选
DA37 有人报名的项目人数 merge + groupby + size inner (default) 只输出有数据的
DA38 所有项目(含0人) merge + left + count left 显示0人项目
DA39 多报名表汇总 concat + merge + count inner 合并多个源数据
DA40 特定人群信息查询 merge + 多条件筛选 + 列选择 inner 输出明细数据

🛠️ 通用技巧总结

场景 推荐做法
合并多个 CSV 报名表 pd.concat([df1, df2], axis=0)
关联项目信息 pd.merge(..., on='item_id')
统计数量 groupby().size() 或 .count()
保留主表全部数据 how='left'
筛选满足多个条件的数据 (cond1) & (cond2)
输出前清理索引 .reset_index(drop=True)
防止拼写错误 检查字段名:df.columns.tolist()

✅ 学习建议

  1. 动手实践:把这几道题的数据自己构造出来跑一遍。
  2. 理解 merge 类型:inner/left/right/outer 的区别是关键。
  3. 掌握 groupby 和 count/size:数据分析最常用组合。

网站公告

今日签到

点亮在社区的每一天
去签到