【Python學習筆記】Pandas實現Excel質檢記錄表初審、復核及質檢統計

背景:

我有這樣一個需要審核的飛書題目表,按日期分成多個sheet,有初審——復核——質檢三個環節,這三個環節是不同的同學在作業,并且領到同一個題目的人選是隨機的,也就是說,完成一道題的三個人之間完全是沒有任何聯系。在這里插入圖片描述
在這里插入圖片描述
我現在需要指定sheet表的范圍,統計一段時間內各環節的數據指標:
初審同學,需要統計每個同學的做題總步數,有效做題步數,還有合格率。
復核同學,需要統計每個同學的做題總步數,有效做題步數,還有合格率。
質檢同學,需要統計每個質檢同學的檢查題目數量。一行就是一道題目,所以質檢同學只需要看寫著他名字的共有幾行就可以。

其中,有效做題步數是指質檢同學檢查后判定為正確的步數,比如一道題共25步,如果質檢認為初審同學做對15步,復核同學做對18步,那么初審有效步數 = 15,復核有效步數 = 18.
初審合格率 = 總初審有效步數 / 初審做題總步數;
復核合格率= 總復核有效步數 / 復核做題總步數;

編寫代碼:

理清上述邏輯之后,下面的工作直接交給GPT:

import pandas as pddef analyze_qc_records(file_path, sheet_names):initial_stats = {}relabel_stats  = {}checker_counts = {}for sheet in sheet_names:df = pd.read_excel(file_path, sheet_name=sheet)for _, row in df.iterrows():# 初審init_name   = row.get('初審同學姓名')  # 取該行“初審同學姓名”,若是空值 (NaN) 則跳過。total_steps = row.get('單題步數', 0) or 0  # 當題目總步數(“單題步數”)缺失或為 NaN 時,設置為 0;否則讀取數值。init_valid  = row.get('初審同學單題有效步數', 0) or 0  # 讀取該行“初審同學單題有效步數”if pd.notna(init_name):st = initial_stats.setdefault(init_name, {'總步數': 0, '有效步數': 0})  # 用 setdefault 保證 initial_stats[姓名] 一定存在,并初始化為 { '總步數':0, '有效步數':0 }st['總步數']   += total_steps  # 每行累加“總步數”和“有效步數”st['有效步數'] += init_valid# 復核relabel_name  = row.get('復核同學姓名')relabel_valid = row.get('復核同學單題有效步數', 0) or 0if pd.notna(relabel_name):  # 如果不是缺失值st = relabel_stats.setdefault(relabel_name, {'總步數': 0, '有效步數': 0})  # 不管 relabel_name 之前在不在 relabel_stats 字典里,調用 setdefault 后,relabel_stats[relabel_name] 一定存在st['總步數']   += total_steps  # 總步數依然用當行的 total_steps —— 即復核同學也「認定」原題的總步數與初審相同st['有效步數'] += relabel_valid# 質檢checker = row.get('質檢同學姓名')if pd.notna(checker):  # 每遇到一行有“質檢同學姓名”,就讓對應姓名的計數 +1checker_counts[checker] = checker_counts.get(checker, 0) + 1# 構建 DataFrame(保留數值合格率)initial_df = pd.DataFrame([{'初審同學姓名': name,'總步數': stats['總步數'],'有效步數': stats['有效步數'],'合格率': stats['有效步數'] / stats['總步數'] if stats['總步數'] else 0}  # 用“有效步數 ÷ 總步數” 得到一個 0–1 之間的小數;若總步數為 0 則直接賦 0,避免除零錯誤。for name, stats in initial_stats.items()])relabel_df = pd.DataFrame([{'復核同學姓名': name,'總步數': stats['總步數'],'有效步數': stats['有效步數'],'合格率': stats['有效步數'] / stats['總步數'] if stats['總步數'] else 0}for name, stats in relabel_stats.items()])checker_df = pd.DataFrame([{'質檢同學姓名': name, '檢查題目數': count}for name, count in checker_counts.items()])# 百分比格式化initial_df['合格率'] = initial_df['合格率'].map(lambda x: f"{x:.2%}")relabel_df['合格率'] = relabel_df['合格率'].map(lambda x: f"{x:.2%}")# 排序 初審/復核 按姓名字母序;質檢按檢查量從高到低。initial_df = initial_df.sort_values(by='初審同學姓名').reset_index(drop=True)relabel_df = relabel_df.sort_values(by='復核同學姓名').reset_index(drop=True)checker_df = checker_df.sort_values(by='檢查題目數', ascending=False).reset_index(drop=True)return initial_df, relabel_df, checker_dfif __name__ == '__main__':# 示例:讀取文件并指定 sheet 范圍file_path = '目錄/質檢記錄.xlsx'xls = pd.ExcelFile(file_path)# 假如想統計第 1 到第 3 張 sheet(索引從 0 開始)selected_sheets = xls.sheet_names[0:3]init_df, relabel_df, checker_df = analyze_qc_records(file_path, selected_sheets)# 打印結果print("初審同學統計:")print(init_df)print("\n復核同學統計:")print(relabel_df)print("\n質檢同學統計:")print(checker_df)# 如需導出到 Excel:with pd.ExcelWriter('目錄/質檢統計結果.xlsx') as writer:init_df.to_excel(writer, sheet_name='初審統計', index=False)relabel_df.to_excel(writer, sheet_name='復核統計', index=False)checker_df.to_excel(writer, sheet_name='質檢統計', index=False)print("統計已導出到 質檢統計結果.xlsx")

輸出結果:

在這里插入圖片描述
結果會直接寫入XLSX文件保存。
并且初審/復核 按姓名字母序排列;質檢按檢查量從高到低排序。
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述
截至目前圓滿實現了我的需求,完美!!

需要注意的點&容易困惑的代碼片段:

1.飛書必須導出為XLSX

因為CSV沒有多個sheet,無法實現跨多張表統計。如果導出成了CSV,你會驚喜地發現只剩下第一張表,后面的數據全丟了。
在這里插入圖片描述
下載為CSV的后果…
在這里插入圖片描述

2.if pd.notna(relabel_name),pd.notna是什么意思?

pd.notna(…) 的作用:
功能:判斷一個值是否 不是 “缺失值”(NaN / None / NaT 等)。

返回:布爾值——如果傳入的 relabel_name 既不是 NaN 也不是 None,則返回 True;否則返回 False。

為什么要用:在讀取 Excel 時,空單元格會被 Pandas 識別為 NaN。只有當姓名字段確實有值時,才要執行后續的統計操作;如果是空的,就跳過這一行,避免在字典里注冊一個空字符串或 NaN 作為鍵。

示例代碼:

import pandas as pdprint(pd.notna("Alice"))   # True,說明 "Alice" 是個有效字符串
print(pd.notna(None))      # False,說明 None 是缺失值
print(pd.notna(float('nan')))  # False,NaN 也是缺失值

這點確實很好用,有的同學填表容易漏項,沒有把信息寫全,留出一些空值在表里,會導致統計數據出現異常,非常的棘手。

3.dict.setdefault(key, default) 的用法?

所屬類型:這是 Python 內置字典 (dict) 的一個方法。

功能:
如果字典中已經有了 key,就直接返回 dict[key];
如果沒有 key,就先把 key: default 這對鍵值對插入字典,然后返回這個 default。

為什么要用:
這樣寫可以保證:不管 relabel_name 之前在不在 relabel_stats 字典里,調用 setdefault 后,relabel_stats[relabel_name] 一定存在,且是一個形如 {‘總步數’: 0, ‘有效步數’: 0} 的初始結構。

之后就可以安心地做 st[‘總步數’] += total_steps、st[‘有效步數’] += relabel_valid這樣步數統計的操作,不用每次都寫一大段 “如果 key 不在,就先賦值” 的邏輯

示例代碼:

d = {}
x = d.setdefault('張三', {'總步數': 0, '有效步數': 0})
# 這時 d == {'張三': {'總步數': 0, '有效步數': 0}}
# 變量 x 就是 {'總步數': 0, '有效步數': 0}# 再次調用
y = d.setdefault('張三', {'總步數': 100, '有效步數': 50})
# 因為 '張三' 已存在,d 不變,y 仍是原來的 {'總步數': 0, '有效步數': 0}print(d)  # {'張三': {'總步數': 0, '有效步數': 0}}

那么回到我們解決問題的代碼:在這里插入圖片描述
結合第二點,這段代碼的作用是:
先用 pd.notna 確保 relabel_name 真有值。
再用 setdefault 拿到或初始化統計結構,省去了手寫“鍵不存在就先賦值”的繁瑣。
最后在 st 上累加步數,就完成了該同學在“初審”或者”復核“環節的統計。
這樣寫既簡潔又安全,不用擔心 KeyError 或把空姓名也算進去。

4.for name, stats in initial_stats.items() ])這個stats是什么?

initial_stats 是你在前面遍歷所有行時累積的一個字典,形如:

{"張三": {"總步數": 120, "有效步數": 110},"李四": {"總步數": 95,  "有效步數": 90},...
}

initial_stats.items() 會返回一個由 (key, value) 對組成的可迭代對象,這里 key 就是每個同學的姓名,value 就是對應的那個小字典(包含 “總步數” 和 “有效步數” 兩個字段)

所以在列表推導里:

for name, stats in initial_stats.items()

name —— 對應同學姓名(例如 “張三”)
stats —— 對應該同學的那個子字典(例如 {“總步數”: 120, “有效步數”: 110})

接下來你就可以用 stats[‘總步數’]、stats[‘有效步數’] 來取出這兩個值,計算合格率:

'合格率': stats['有效步數'] / stats['總步數'] if stats['總步數'] else 0

如果覺得 stats 這個名字不直觀,也可以任意改成別的,比如 data、counts、vals,邏輯完全一樣:它只是“每個同學對應的那份統計數據”的一個變量名。

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

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

相關文章

守護進程編程、GDB調試以及外網連接樹莓派

目錄 一、什么是守護進程以及如何創建守護進程1. 什么是守護進程?2. 如何創建守護進程? 二、什么是GDB調試以及如何用GDB命令調試C程序1. 什么是GDB?2. 如何用GDB命令調試C程序? 三、外網訪問樹莓派 一、什么是守護進程以及如何創…

Logisim數字邏輯實訓——計數器設計與應用

4位遞增計數器 六進制計數器 十進制計數器 六十進制計數器 二十四進制計數器 計時器

發現“橫”字手寫有難度,對比兩個“橫”字

我發現手寫體“橫”字“好看”程度&#xff0c;難以比得上印刷體&#xff1a; 兩個從方正簡體啟體來的“橫”字&#xff1a; 哪個更好看&#xff1f;我是傾向于左邊一點。 <div style"transform: rotate(180deg); display: inline-block;"> 左邊是我從方正簡…

ubuntu 向右拖動窗口后消失了、找不到了

這是目前單顯示器的設置&#xff0c;因為實際只有1個顯示器&#xff0c;之前的設置如下圖所示&#xff0c;有2個顯示器&#xff0c;一個主顯示器&#xff0c;一個23寸的顯示器 ubuntu 22.04 系統 今天在操作窗口時&#xff0c;向右一滑&#xff0c;發現這個窗口再也不顯示了、找…

專精特新政策推動,B端UI設計如何賦能中小企業創新發展?

在當前數字化轉型浪潮下&#xff0c;專精特新政策為中小企業提供了強大的支持&#xff0c;助力其在細分領域實現專業化、精細化、特色化和創新化發展。B端UI設計作為提升企業數字化產品用戶體驗和工作效率的重要手段&#xff0c;能夠有效賦能中小企業創新發展。本文將探討專精特…

梯度下降代碼

整體流程 數據預處理:標準化->加一列全為1的偏置項 訓練:梯度下降,將數學公式轉換成代碼 預測 模型代碼 import numpy as np# 標準化函數&#xff1a;對特征做均值-方差標準化 # 返回標準化后的特征、新數據的均值和標準差&#xff0c;用于后續預測def standard(feats…

RAG 實戰|用 StarRocks + DeepSeek 構建智能問答與企業知識庫

文章作者&#xff1a; 石強&#xff0c;鏡舟科技解決方案架構師 趙恒&#xff0c;StarRocks TSC Member &#x1f449; 加入 StarRocks x AI 技術討論社區 https://mp.weixin.qq.com/s/61WKxjHiB-pIwdItbRPnPA RAG 和向量索引簡介 RAG&#xff08;Retrieval-Augmented Gen…

從零開始學A2A一:A2A 協議的高級應用與優化

A2A 協議的高級應用與優化 學習目標 掌握 A2A 高級功能 理解多用戶支持機制掌握長期任務管理方法學習服務性能優化技巧 理解與 MCP 的差異 分析多智能體場景下的優勢掌握不同場景的選擇策略 第一部分&#xff1a;多用戶支持機制 1. 用戶隔離架構 #mermaid-svg-Awx5UVYtqOF…

【C++】入門基礎【上】

目錄 一、C的發展歷史二、C學習書籍推薦三、C的第一個程序1、命名空間namespace2、命名空間的使用3、頭文件<iostream>是干什么的&#xff1f; 個人主頁<—請點擊 C專欄<—請點擊 一、C的發展歷史 C的起源可以追溯到1979年&#xff0c;當時Bjarne Stroustrup(本…

1panel第三方應用商店(本地商店)配置和使用

文章目錄 引言資源網站實戰操作說明 引言 1Panel 提供了一個應用提交開發環境&#xff0c;開發者可以通過提交應用的方式將自己的應用推送到 1Panel 的應用商店中&#xff0c;供其他用戶使用。由此衍生了一種本地應用商店的概念&#xff0c;用戶可以自行編寫應用配置并上傳到自…

Evidential Deep Learning和證據理論教材的區別(主要是概念)

最近終于徹底搞懂了Evidential Deep Learning&#xff0c;之前有很多看不是特別明白的地方&#xff0c;原來是和證據理論教材&#xff08;是的&#xff0c;不只是國內老師寫的&#xff0c;和國外的老師寫的教材出入也比較大&#xff09;的說法有很多不一樣&#xff0c;所以特地…

text-decoration: underline;不生效

必須得紀念一下&#xff0c;在給文本加下劃線時&#xff0c;發現在win電腦不生效&#xff0c;部分mac也不生效&#xff0c;只有個別的mac生效了&#xff0c;思考了以下幾種方面&#xff1a; 1.兼容性問題&#xff1f; 因為是electron項目&#xff0c;不存在瀏覽器兼容性問題&…

VUE SSR(服務端渲染)

&#x1f916; 作者簡介&#xff1a;水煮白菜王&#xff0c;一位前端勸退師 &#x1f47b; &#x1f440; 文章專欄&#xff1a; 前端專欄 &#xff0c;記錄一下平時在博客寫作中&#xff0c;總結出的一些開發技巧和知識歸納總結?。 感謝支持&#x1f495;&#x1f495;&#…

ARCGIS國土超級工具集1.5更新說明

ARCGIS國土超級工具集V1.5版本更新說明&#xff1a;因作者近段時間工作比較忙及正在編寫ARCGISPro國土超級工具集&#xff08;截圖附后&#xff09;的原因&#xff0c;故本次更新為小更新&#xff08;沒有增加新功能&#xff0c;只更新了已有的工具&#xff09;。本次更新主要修…

劉鑫煒履新共工新聞社新媒體研究院院長,賦能媒體融合新征程

2025年4月18日&#xff0c;大灣區經濟網戰略媒體共工新聞社正式對外宣布一項重要人事任命&#xff1a;聘任螞蟻全媒體總編劉鑫煒為新媒體研究院第一任院長。這一舉措&#xff0c;無疑是對劉鑫煒在新媒體領域卓越專業能力與突出行業貢獻的又一次高度認可&#xff0c;也預示著共工…

java基礎從入門到上手(九):Java - List、Set、Map

一、List集合 List 是一種用于存儲有序元素的集合接口&#xff0c;它是 java.util 包中的一部分&#xff0c;并且繼承自 Collection 接口。List 接口提供了多種方法&#xff0c;用于按索引操作元素&#xff0c;允許元素重復&#xff0c;并且保持插入順序。常用的 List 實現類包…

UWP發展歷程

通用Windows平臺(UWP)發展歷程 引言 通用Windows平臺(Universal Windows Platform, UWP)是微軟為實現"一次編寫&#xff0c;處處運行"的愿景而打造的現代應用程序平臺。作為微軟統一Windows生態系統的核心戰略組成部分&#xff0c;UWP代表了從傳統Win32應用向現代應…

git忽略已跟蹤的文件/指定文件

在項目開發中&#xff0c;有時候我們并不需要git跟蹤所有文件&#xff0c;而是需要忽略掉某些指定的文件或文件夾&#xff0c;怎么操作呢&#xff1f;我們分兩種情況討論&#xff1a; 1. 要忽略的文件之前并未被git跟蹤 這種情況常用的方法是在項目的根目錄下創建和編輯.gitig…

AI 組件庫是什么?如何影響UI的開發?

AI組件庫是基于人工智能技術構建的、面向用戶界面&#xff08;UI&#xff09;開發的預制模塊集合。它們結合了傳統UI組件&#xff08;如按鈕、表單、圖表&#xff09;與AI能力&#xff08;如機器學習、自然語言處理、計算機視覺&#xff09;&#xff0c;旨在簡化開發流程并增強…

【Win】 cmd 執行curl命令時,輸出 ‘命令管道位置 1 的 cmdlet Invoke-WebRequest 請為以下參數提供值: Uri: ’ ?

1.原因&#xff1a; 有一個名為 Invoke-WebRequest 的 CmdLet&#xff0c;其別名為 curl。因此&#xff0c;當您執行此命令時&#xff0c;它會嘗試使用 Invoke-WebRequest&#xff0c;而不是使用 curl。 2.解決辦法 在cmd中輸入如下命令刪除這個curl別名&#xff1a; Remov…