Python 數據分析與可視化 Day 7 - 可視化整合報告實戰

好的,我們進入:


🧠 第5周 · 第7天

🎯 主題:測試復盤 + 項目封裝實戰


? 今日目標

  • 回顧第5周數據分析與可視化核心知識
  • 對整個“學生成績分析系統”進行項目封裝與模塊化拆分
  • 增加命令行參數支持,提升可復用性與實用性
  • 打包輸出完整分析報告

📚 一、本周復盤重點

模塊核心技能工具庫
數據清洗缺失值處理、類型轉換pandas
數據篩選條件過濾、排序pandas
分組聚合groupby、agg、pivot_tablepandas
可視化折線圖、直方圖、箱線圖等matplotlib / seaborn
報告整合Markdown 輸出、圖表嵌入文件系統操作

🛠 二、項目封裝建議(結構)

student_report_project/
├── data/
│   └── students_cleaned.csv
├── charts/
│   └── (生成的圖表)
├── scripts/
│   ├── clean_data.py
│   ├── filter_and_sort.py
│   ├── groupby_agg_analysis.py
│   ├── visualize_students.py
│   ├── generate_report.py
│   └── main.py  👈 綜合入口(命令行參數)
├── README.md

🧩 三、命令行支持示例:main.py

import argparse
import subprocessparser = argparse.ArgumentParser(description="學生成績分析工具")
parser.add_argument('--step', type=str, help="選擇執行步驟,如 clean | visualize | report | all")
args = parser.parse_args()if args.step == "clean":subprocess.run(["python", "scripts/clean_data.py"])
elif args.step == "visualize":subprocess.run(["python", "scripts/visualize_students.py"])
elif args.step == "report":subprocess.run(["python", "scripts/generate_report.py"])
elif args.step == "all":subprocess.run(["python", "scripts/clean_data.py"])subprocess.run(["python", "scripts/visualize_students.py"])subprocess.run(["python", "scripts/generate_report.py"])
else:print("? 請輸入有效的步驟參數:clean / visualize / report / all")

運行方式:

python scripts/main.py --step all

🧪 今日練習任務

  1. 封裝你的所有分析腳本到 scripts/ 文件夾中
  2. generate_report.py 的報告輸出路徑與圖表目錄一致管理
  3. 在命令行運行 main.py --step all 一鍵完成數據分析 → 可視化 → 報告輸出

代碼輸出:

  1. clean_data.py

    # clean_data.py placeholder script
    import pandas as pd
    import os
    def clean_data():# 原始數據路徑(假設為 data/raw_students.csv)raw_path = "./data/students_dirty.csv"cleaned_path = "./data/students_cleaned.csv"# 檢查文件是否存在if not os.path.exists(raw_path):raise FileNotFoundError(f"? 找不到原始數據文件:{raw_path}")# 讀取原始數據df = pd.read_csv(raw_path)print("? 已加載原始數據:")print(df.head())# ---------------- 清洗步驟 ----------------# 1. 刪除空行或全部為 NaN 的行df.dropna(how="all", inplace=True)# 2. 填充缺失值(如成績)df["成績"] = pd.to_numeric(df["成績"], errors="coerce")  # 轉換為數字df.fillna({"成績": df["成績"].mean()}, inplace=True)  # 填充姓名和性別的缺失值# 3. 創建新列:是否及格df["是否及格"] = df["成績"] >= 60# 4. 去除重復值(如姓名+性別+成績完全重復)df.drop_duplicates(subset=["姓名", "性別", "成績"], inplace=True)# 5. 標準化性別字段df["性別"] = df["性別"].str.strip().replace({"男生": "男", "女生": "女"})# 6. 按姓名升序排序df.sort_values(by="姓名", inplace=True)# 7. 重置索引df.reset_index(drop=True, inplace=True)# ---------------- 保存清洗后的數據 ----------------os.makedirs("data", exist_ok=True)df.to_csv(cleaned_path, index=False, encoding="utf-8")print(f"\n? 清洗完成,保存至:{cleaned_path}")print(f"? 數據清理完成,已保存到 {cleaned_path}")if __name__ == "__main__":clean_data()
    
  2. filter_and_sort.py

    # filter_and_sort.py placeholder script
    import pandas as pd
    import osdef filter_and_sort():# 輸入路徑input_path = "./data/students_cleaned.csv"# 檢查數據文件是否存在if not os.path.exists(input_path):raise FileNotFoundError("? 找不到 students_cleaned.csv,請先運行 clean_data.py")# 加載清洗后的數據df = pd.read_csv(input_path)print("? 已加載數據:")print(df.head())# ------------------- 篩選操作 -------------------# 1. 篩選:成績大于等于 80 的學生print("\n🎯 成績 >= 80 的學生:")high_scores = df[df["成績"] >= 80]print(high_scores)# 2. 篩選:未及格的學生(是否及格為 False)print("\n🚨 未及格的學生:")failed_students = df[df["是否及格"] == False]print(failed_students)# 3. 篩選:性別為“女”且成績大于 85print("\n👩 女生中成績 > 85 的學生:")excellent_girls = df[(df["性別"] == "女") & (df["成績"] > 85)]print(excellent_girls)# ------------------- 排序操作 -------------------# 4. 成績從高到低排序print("\n🏆 學生成績從高到低排序:")sorted_scores = df.sort_values(by="成績", ascending=False)print(sorted_scores)# 5. 多列排序:先按是否及格,再按成績降序print("\n🔍 先按是否及格,再按成績排序:")multi_sorted = df.sort_values(by=["是否及格", "成績"], ascending=[False, False])print(multi_sorted)# (可選)保存篩選結果os.makedirs("./data", exist_ok=True)high_scores.to_csv("./data/high_scores.csv", index=False)failed_students.to_csv("./data/failed_students.csv", index=False)print("\n? 高分/不及格學生已分別保存至 data/ 目錄下。")if __name__ == "__main__":filter_and_sort()print("? 篩選和排序操作完成!")
    
  3. generate_report.py

    # generate_report.py placeholder script
    import pandas as pd
    import osdef generate_report():# 路徑配置input_path = "./data/students_cleaned.csv"charts_dir = "./charts"report_path = os.path.join(charts_dir, "學生成績可視化報告.md")# 檢查必要文件是否存在if not os.path.exists(input_path):raise FileNotFoundError("? 缺少清洗后的數據文件:students_cleaned.csv")if not os.path.exists(charts_dir):raise FileNotFoundError("? 圖表目錄不存在,請先運行 visualize_students.py")# 加載數據df = pd.read_csv(input_path)# 數據統計total = len(df)avg_score = df["成績"].mean()max_score = df["成績"].max()min_score = df["成績"].min()pass_rate = df["是否及格"].mean() * 100score_diff = df.groupby("性別")["成績"].mean().diff().abs().values[-1]# Markdown 報告模板report_md = f"""# 📝 學生成績數據分析與可視化報告## 1. 數據概況- 總人數:**{total} 人**
    - 平均成績:**{avg_score:.2f} 分**
    - 成績范圍:**{min_score} - {max_score} 分**
    - 及格率:**{pass_rate:.1f}%**
    - 男女生成績差異約:**{score_diff:.2f} 分**---## 2. 成績趨勢折線圖
    ![成績折線圖](成績折線圖.png)## 3. 成績柱狀圖
    ![成績柱狀圖](成績柱狀圖.png)## 4. 性別平均成績柱狀圖
    ![性別平均成績柱狀圖](性別平均成績柱狀圖.png)## 5. 成績分布直方圖
    ![成績分布直方圖](成績分布直方圖.png)## 6. 成績箱線圖(按性別)
    ![成績箱線圖_按性別](成績箱線圖_按性別.png)---## 7. 分析結論與建議- 成績整體集中在 **XX ~ XX** 分之間(可從直方圖查看)
    - 存在少量低分/高分的異常值(見箱線圖)
    - 性別差異不明顯,但女生略高 / 男生略高
    - 建議關注及格率波動、低分段學生的提升空間---*由 Python + Pandas + Matplotlib + Seaborn 自動生成* ?"""# 保存報告with open(report_path, "w", encoding="utf-8") as f:f.write(report_md)print(f"? 分析報告已生成:{report_path}")if __name__ == "__main__": generate_report()print("? 學生成績分析報告生成完畢!請查看 charts/ 目錄下的學生成績可視化報告.md")print("🎉 感謝使用學生成績分析工具!")
    
  4. groupby_agg_analysis.py

    # groupby_agg_analysis.py placeholder script
    import pandas as pd
    import osdef groupby_agg_analysis():# 數據路徑input_path = "./data/students_cleaned.csv"# 檢查數據文件是否存在if not os.path.exists(input_path):raise FileNotFoundError("? 缺少 students_cleaned.csv,請先運行 clean_data.py")# 讀取數據df = pd.read_csv(input_path)print("? 已加載學生數據:")print(df.head())# ------------------- 一、按性別分組統計 -------------------print("\n👥 按性別分組的成績統計:")gender_stats = df.groupby("性別")["成績"].agg(["count", "mean", "max", "min"]).rename(columns={"count": "人數", "mean": "平均成績", "max": "最高分", "min": "最低分"})print(gender_stats)# ------------------- 二、按是否及格統計人數 -------------------print("\n🎯 統計及格 / 不及格人數:")pass_count = df["是否及格"].value_counts().rename(index={True: "及格", False: "不及格"})print(pass_count)# ------------------- 三、性別 + 是否及格的交叉分析 -------------------print("\n📊 性別與是否及格交叉表:")cross_tab = pd.crosstab(df["性別"], df["是否及格"])print(cross_tab)# ------------------- 四、按性別分組后計算及格率 -------------------print("\n? 按性別分組的及格率(%):")pass_rate_by_gender = (df.groupby("性別")["是否及格"].mean().multiply(100).round(2).rename("及格率"))print(pass_rate_by_gender)# (可選)保存分析結果os.makedirs("./data", exist_ok=True)gender_stats.to_csv("./data/gender_score_summary.csv")cross_tab.to_csv("./data/crosstab_gender_pass.csv")pass_rate_by_gender.to_csv("./data/pass_rate_by_gender.csv")print("\n📁 分組聚合分析結果已保存至 data/ 目錄。")if __name__ == "__main__":groupby_agg_analysis()print("? 分組聚合分析完成!")
    
  5. visualize_students.py

    # visualize_students.py placeholder scriptimport pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    import osdef visualize_students():# 中文字體適配(根據系統配置可選)plt.rcParams['font.family'] = 'Arial Unicode MS'  # macOS# plt.rcParams['font.sans-serif'] = ['SimHei']     # Windows 中文支持plt.rcParams['axes.unicode_minus'] = False# 路徑配置input_path = "./data/students_cleaned.csv"output_dir = "./charts"os.makedirs(output_dir, exist_ok=True)# 加載數據df = pd.read_csv(input_path)print("? 已加載數據:")print(df.head())# ================= 圖表 1:成績折線圖 =================plt.figure(figsize=(8, 5))plt.plot(df["姓名"], df["成績"], marker='o')plt.title("學生成績折線圖")plt.xlabel("姓名")plt.ylabel("成績")plt.grid(True)plt.xticks(rotation=45)plt.tight_layout()plt.savefig(f"{output_dir}/成績折線圖.png")plt.close()# ================= 圖表 2:成績柱狀圖 =================plt.figure(figsize=(8, 5))plt.bar(df["姓名"], df["成績"], color="skyblue")plt.title("學生成績柱狀圖")plt.xlabel("姓名")plt.ylabel("成績")plt.xticks(rotation=45)plt.tight_layout()plt.savefig(f"{output_dir}/成績柱狀圖.png")plt.close()# ================= 圖表 3:性別平均成績柱狀圖 =================plt.figure(figsize=(6, 4))sns.barplot(data=df, x="性別", y="成績", estimator="mean", palette="Set2")plt.title("性別平均成績柱狀圖")plt.tight_layout()plt.savefig(f"{output_dir}/性別平均成績柱狀圖.png")plt.close()# ================= 圖表 4:成績分布直方圖 =================plt.figure(figsize=(6, 4))sns.histplot(df["成績"], bins=5, kde=True, color="orange")plt.title("成績分布直方圖")plt.xlabel("成績")plt.tight_layout()plt.savefig(f"{output_dir}/成績分布直方圖.png")plt.close()# ================= 圖表 5:成績箱線圖(按性別) =================plt.figure(figsize=(6, 4))sns.boxplot(data=df, x="性別", y="成績", palette="Pastel1")plt.title("成績箱線圖(按性別)")plt.tight_layout()plt.savefig(f"{output_dir}/成績箱線圖_按性別.png")plt.close()print(f"\n? 所有圖表已保存至:{output_dir}/")if __name__ == "__main__": visualize_students()print("? 學生成績數據可視化完成!")
    

🧾 今日總結

  • 對第5周內容完成了全面回顧與實戰項目封裝
  • 掌握了命令行工具腳本的基本設計方式
  • 具備將數據分析過程“自動化、可配置、可交付”的能力

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912363.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912363.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣1498. 滿足條件的子序列數目隨筆

“方生方死,方死方生。”——《莊子》 題目 給你一個整數數組 nums 和一個整數 target 。 請你統計并返回 nums 中能滿足其最小元素與最大元素的 和 小于或等于 target 的 非空 子序列的數目。 由于答案可能很大,請將結果對 取余后返回。 難度&#…

5.Docker安裝Tomcat

#官方的使用 docker run -it --rm tomcat:9.0 #我們之前使用docker run -d 某鏡像都是后來運行,容器停止之后,容器還能夠查詢到 而docker run -it -rm 是用完之后,容器刪除,鏡像還存在。 測試的時候可以用官方的 &#xff08…

企業事業政府單位智慧主題展廳素材管理平臺播放軟件

以下為企事業單位及政府智慧主題展廳素材管理平臺播放軟件的核心功能簡介,綜合多維度技術實現統一管控與智能展示: 一、內容資產管理 全格式素材支持? 兼容視頻、3D模型、圖文、AR/VR場景等多媒體格式,支持批量導入與云端存儲。 智能分類與…

Python+FastAPI的一些語法與問題解決

Q1:result await dbsession.execute(text(sql_context),params) 如何把result轉成key,value的字典列表 A1: 使用SQLAlchemy的mappings()方法獲取字典形式的結果集: result await db_session.execute(text(sql_context), params) dict_list [dict(row) for row…

Reactor并發無關性

Reactor,像 RxJava 一樣,可以被認為是 并發無關(concurrency-agnostic) 的。這意味著它不強制要求任何特定的并發模型,而是將選擇權交給開發者。換句話說,Reactor 不會強制你使用多線程或異步編程&#xff…

#華為昇騰#華為計算#昇騰開發者計劃2025#

#華為昇騰#華為計算#昇騰開發者計劃2025# 通過學習Ascend C算子開發的初級教程&#xff0c;通過課程講解及樣例實操&#xff0c;幫助我學習使用Ascend C開發自己的算子。收獲很大。 <新版開發者計劃>的內容鏈接&#xff1a;https://www.hiascend.com/developer-program_2…

FLOPS、FLOP/s、TOPS概念

在計算性能和硬件指標中&#xff0c;FLOPS、FLOP/s、TOPS 是常見的術語&#xff0c;但它們有明確的區別和應用場景。以下是詳細解析&#xff1a; 1. FLOPS&#xff08;Floating Point Operations per Second&#xff09; 定義&#xff1a; 每秒浮點運算次數&#xff08;Floati…

Windows所有系統自帶.NET Framework版本win7,win10,win11預裝.NET版本

Windows系統支持“.NET版本”匯總 本文詳細列出了Windows從NT4.0到Windows11各版本自帶的.NETFramework版本及對應最高兼容的.NETFramework版本&#xff0c;便于了解不同Windows系統之間的.NETFramework更新歷史。 以下匯總了Windows每個版本自帶的“.NET版本”&#xff0c;與…

Windows 下使用 nvm 管理 Node.js 多版本 —— 完整指南

Node.js 版本更新頻繁&#xff0c;不同項目可能依賴不同的版本&#xff0c;手動切換極為麻煩。nvm-windows 是專為 Windows 用戶開發的 Node.js 多版本管理工具&#xff0c;可以輕松地安裝、切換、卸載 Node.js 版本。 本篇將從下載到實際使用&#xff0c;手把手帶你玩轉 nvm-…

vue使用Element Plus UI框架

您好&#xff0c;艦長&#xff01;非常棒的選擇。功能是應用的骨架&#xff0c;而美觀的 UI 則是應用的靈魂和血肉。是時候為我們的飛船進行一次全面的“外觀升級”和“內飾裝修”了。 我們將集成一個在業界非常流行、功能強大的 Vue 3 組件庫——Element Plus。它將幫助我們快…

【ubuntu24.04】忘了自己把開機samba掛載的腳本放哪里了

從兩個方面來定位這幾個 Samba 掛載點&#xff1a; 一、查看當前已經掛載的 CIFS/SMB 文件系統 使用 mount mount | grep -i cifs或者 mount | grep -E (smb|cifs)這會列出所有當前活躍的 CIFS/SMB 掛載&#xff0c;比如&#xff1a; //192.168.1.100/share on /mnt/data type …

在 Windows 上使用 Docker Desktop 快速搭建本地 Kubernetes 環境(附詳細部署教程)

言簡意賅的講解Docker Desktop for Windows搭建Kubernetes解決的痛點 目標讀者&#xff1a; 對 Docker Desktop 有一定了解&#xff0c;能在 Windows 上成功安裝和使用 Docker Desktop。想要在本地快速搭建一套 Kubernetes 環境進行測試或學習的開發者。 一、準備工作 安裝 Doc…

dockercompose快速安裝ELK

第一步&#xff1a;環境準備 請確保您的機器上已經安裝了 Docker 和 Docker Compose。 第二步&#xff1a;創建項目目錄和配置文件 為了讓 Docker Compose 能夠正確地構建和管理容器&#xff0c;我們需要創建一個特定的目錄結構。 創建一個主目錄&#xff0c;例如 elk-stack。…

閑聊ARM內核參數傳遞機制

之前一直沒怎么在意這個問題&#xff0c;直到最近搞了個奇奇怪怪的項目&#xff0c;才發現這部分知識得補上來&#xff0c;記錄一下。 ARM有一個標準&#xff0c;叫《Procedure Call Standard for the Arm Architecture》&#xff0c;人話就是ARM架構過程調用標準&#xff0c;…

萬興喵影Filmora AI Video v14.7.03國際高級版,AI視頻剪輯全能工具,一鍵專業級創作?

[軟件名稱]: 萬興喵影Filmora AI Video v14.7.03 [軟件大小]: 199.4 MB [下載通道]: 夸克盤 | 迅雷盤 軟件介紹 &#x1f3ac;《萬興喵影》v14.7.03國際高級版&#xff5c;AI智能剪輯神器&#xff0c;解鎖全功能無水印&#xff01; ? 核心優勢&#xff1a; ? 1000背景音…

暴力風扇方案介紹

炎炎夏日&#xff0c;當普通風扇只能送來 “溫柔拂面”&#xff0c;暴力風扇卻能吹出 “臺風級” 清涼&#xff01;想知道這些 “風力狂魔” 是如何煉成的&#xff1f;答案藏在電機、電路和芯片的黃金三角組合里。? 一、電機&#xff1a;暴力風扇的 “心臟起搏器”? 暴力風扇…

pyqt小問題匯總

文章目錄 1、inherit global site-packages2、setGeometry(10,20,30,40)setGeometry(x, y, width, height)1. **x參數**2. **y參數**3. **width參數**4. **height參數** 示例說明與其他方法的對比注意事項示例代碼 1、inherit global site-packages 在pycharm 創建項目時&…

提升JavaScript性能的六大關鍵策略

1、優化代碼結構與算法 避免使用嵌套循環&#xff0c;改用更高效的算法如哈希表或二分查找。減少不必要的計算&#xff0c;緩存重復使用的計算結果。使用時間復雜度更低的算法替代高復雜度操作。優化遞歸調用&#xff0c;避免棧溢出和性能瓶頸。改用迭代或尾遞歸優化。簡化條件…

打造跨平臺應用的全能框架:Dioxus

在如今飛速發展的數字世界中,越來越多的開發者開始尋找能夠滿足跨平臺需求的高效框架。而在這些選擇中,Dioxus這個全棧應用框架脫穎而出。Dioxus是一款為Web、桌面和移動端開發而設計的全棧框架,采用Rust語言,具備跨平臺、一體化的優勢。本文將深入介紹Dioxus的獨特功能,應…

大事件項目記錄5-用戶接口開發-更新用戶頭像

5&#xff09;更新用戶頭像。 UserController.java&#xff1a; PatchMapping("updateAvatar")public Result updateAvatar(RequestParam String avatarUrl){userService.updateAvatar(avatarUrl);return Result.success();} UserService.java&#xff1a; UserServ…