🔷 DA37:統計運動會項目報名人數(僅輸出有人報名的項目)
? 題目描述
給定兩個 CSV 文件:
items.csv
:包含項目信息(item_id, item_name, location)signup.csv
:包含員工報名信息(employee_id, name, sex, department, item_id)
要求:統計每個項目的報名人數,只輸出報名人數不為 0 的項目。
💡 即:只要有人報了的項目才顯示。
? 正確代碼
import pandas as pddf_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 pddf_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.csv
和 signup1.csv
合并后,再統計各項目的報名人數(只輸出有人報名的)。
? 正確代碼
import pandas as pditem = 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>| :或</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() |
? 學習建議
- 動手實踐:把這幾道題的數據自己構造出來跑一遍。
- 理解 merge 類型:inner/left/right/outer 的區別是關鍵。
- 掌握 groupby 和 count/size:數據分析最常用組合。