實踐-彙總大量EXCEL-Pandas

1.背景介紹

寫這篇文章出於兩個目的:
第一:肯定是想介紹一下標題的方法。
第二:想嘗試着用markdown來寫博客,順便學習一下這個工具。
背景:
最近我導師要我幫忙在學習通上,導出他教的某兩個課程(一個理論,一個實驗)的各8次作業成績表和8次簽到表,1次期中成績,1次期末成績。也就是 實驗課 有18張表彙總成一個統計表, 理論課 18張表彙總成一個統計表,總共要處理共36張表。然後把成績複製到統計表中,要對應好每一個學號的學生。這些表都是按一定規則進行排序的,所以每個表的排序情況是不一樣的,把每張表對應的學生的成績複製到彙總表的中,難度和工作量非常大。首先我不可能老實到每一張表去找一個學生的成績再複製到彙總表,那也太麻煩了。

2.手動複製到excel

本來一開始我就想用代碼,使用pandas來處理的。但是仔細想了一想辦法,發現手動的工作量應該也不是很大。首先我進行了以下操作:

2.1 處理統計表

從某張表中首先把學號,姓名複製出來放到統計表中,在excel中按學號升序排序;在這裏插入圖片描述

2.2 處理作業表

在每一張表中也按學號升序排序,把作業成績那一列複製到總表裏。問題不大!!

2.3 處理簽到表

麻煩就開始來了!
1. 前幾行有多餘的行,得先刪除才能排序。
在這裏插入圖片描述
2. 以下圖片中的值都是文字表示的簽到狀態,我總不可能一個個手動更改成數字成績吧。
簽到表其中沒有成績,只有幾種狀態的文字,所以調用 excel函數:

=IF(OR(F2="已籤",F2="教師代簽"),1,IF(F2="簽到已過期",0.5,IF(F2="缺勤",0,)))

在這裏插入圖片描述
OK!搞定複製到統計表。但是這只是一張表,我還有7張+8張 。。ToT。。

2.4 期中,期末成績表

同樣刪掉前幾各無關行,按學號排序,取成績,複製到統計表。

2.5 彙總-總成績

8個作業(每門100分)佔總成績的16%,簽到佔8%,期中成績佔%30,期末成績佔46%。咋把這個成績按比例轉換匯總到總成績呢?
想了想就是尺度縮放,有點像機器學習裏面的歸一化的思想。
比如作業:先把8門成績加起來,再除以最大800分,得到一個比例,然後 16%最大佔總成績16分,用16乘以比例就得到轉轉的成績了。
newscore=rawscore.summaxrawsocreratiomaxnewscore newscore=\frac{rawscore.sum}{maxrawsocre} *ratio*maxnewscore

=(SUM(C4:J4)*16/800)+SUM(K4:R4)+(S4*30/100)+(T4*46/100)

以上,處理完畢!!從開始到找方法,操作解決各種問題,花了我將近4個小時才完成。 要是再來一次肯定就快了,大概一到兩個小時的樣子吧。1個課程作業就2個小時,要是我導師把他教的課程,期末成績都丟給我,豈不是人都要搞傻。。。

3.使用Python+Pandas處理excel文件

痛定思痛,避免後面花過多時間折騰,還不如一次就使用代碼來批處理搞定,這樣你丟再多,咱也接着。還能避免導師查崗,摸摸魚。爽!開幹!

3.1 Pandas-讀取excel

3.1.1 讀取總表

statistic_table=pd.read_excel('./總評成績計算表.xlsx',sheet_name='理論')

第一個參數:路徑+文件名
第二個參數(可選):Excel的Sheet名,默認是選擇該表第一個sheet

3.1.2 讀取作業表,簽到表

#讀取作業表
#使用list來將讀取出的表暫存起來
assignments=[]
for ass_i in range(1,9):
        ass_table=pd.read_excel('./intro/ass{0}.xls'.format(ass_i))
        assignments.append(ass_table)

3.1.3 讀取期中,期末表

#讀取期中表
midterm=pd.read_excel('./intro/Midterm.xls')
#讀取期末表
finalterm=pd.read_excel('./intro/Final.xls')       

3.2 預處理

在這裏插入圖片描述
因爲表的結構不是標準結構,可以看到前面都是很亂的,要麼自己手動處理原表刪掉不相干的行,要麼使用索引來操作。由於習慣使用numpy我傾向於後者。
不同表對應的統計表的列號

#統計表中列名對應的列
name2index=dict()
#作業
for i in range(2,10):
    name2index['ass{}'.format(i-1)]=i
#簽到
for i in range(10,18):
    name2index['sign{}'.format(i-9)]=i
name2index['mid']=18
name2index['final']=19
name2index['total']=20
name2index

3.3 Pandas索引切片

pd.iloc[raw,line]
raw:行號
line:列號
使用參考:

https://blog.csdn.net/w_weiying/article/details/81411257

3.4 Pandas遍歷

pd .iteritems()
將DataFrame迭代爲(列名, Series)對
使用參考:

https://www.cnblogs.com/keye/p/9673393.html

3.5 Pandas查找並取出某值所在的行

table.isin([name]),查找name所在的索引,返回bool值

table.iloc[:,1].isin([name]):查找table第一列name所在的行號

table[table.iloc[:,1].isin([name])]:將找到的name行號,將該所在行值取出來。

3.6 Pandas 給表賦值

table.iloc[i,j]=val
給表i和j位置賦值爲val

3.7 綜合代碼

#先取出2至最後一行的第0列,也就是取出所有學號
sid_table=statistic_table.iloc[2:,0]
#遍歷表,對應每一個學號所在的行號以及學號
for sid_ix,sid in sid_table.iteritems():
    #遍歷學號
    #統計表的行值:sid_ix
    ass_scores=[] #用來保存該學號的所有作業成績
    #遍歷作業表把對應成績放到對應列
    for ass_ix,ass_table in enumerate(assignments):
        #該表在統計表的列值
        name_ix=name2index['ass{}'.format(ass_ix+1)]
        #取出每個表對應學號的作業成績
        score=float(ass_table[ass_table.iloc[:,1].isin([sid])].iloc[:,9].values[0])
        ass_scores.append(score)
        #將對應值插入統計表中
        statistic_table.iloc[sid_ix,name_ix]=score

後面的表操作都差不多了,按照代碼仔細debug,把對應表的值都取出來然後賦值給總表,就ok了。

總結:

本篇博客的內容主要是來自我自己處理excel的真實案例,首先介紹如何手動操作excel,通過一些技巧批量處理和複製。隨後使用python,利用pandas的一些操作來處理excel達到批量處理的效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章