【Python】openpyxl統計2019年數學建模獲獎情況【2】


統計某一文件夾下所有表格數據並寫入一個新的表格

統計了2019年6道賽題每道賽題每個大學的獲獎情況以及所有賽題每個大學的獲獎情況,隊伍數只統計隊長所在學校,我這里F題和A題的獲獎名單是相同的

 

 

  1 import openpyxl
  2 import os
  3  4
  5 class ExceltoExcel():
  6 
  7     def __init__(self, file, new_sheet):
  8         self.universityData = {}
  9         self.wb = openpyxl.load_workbook(file)
 10         # self.wb_new =openpyxl.Workbook()  # 新建一個表格來存儲生成的數據
 11         self.sheet = self.wb.active
 12         self.new_sheet = new_sheet  # 新表單
 13         self.maxrow = self.sheet.max_row
 14         self.maxcol = self.sheet.max_column
 15 
 16 
 17     def excel_to_dict(self):
 18         '''
 19         統計每個大學全部的獲獎數量,分別列出是幾等獎和對應的數量
 20         {'同濟大學':{'一等獎':{'team':1,'num'=3},'二等獎':{'team':2,'num'=6},'三等獎':{'team':1,'num'=3},'成功參與獎':{'team':1,'num'=3}},
 21         '清華大學':{'一等獎':{'team':1,'num'=3},'二等獎':{'team':1,'num'=3},'三等獎':{'team':1,'num'=3},'成功參與獎':{'team':1,'num'=3}},...}
 22         統計所有人數
 23         Fill in universityData with each rewardship‘s popularity
 24         '''
 25         # tolal_team = self.maxrow
 26         for row in range(2, self.maxrow + 1):
 27             # 取每個單元格的數據
 28             sheet_col = ['F', 'H', 'J']
 29             rewardcell = self.sheet['D' + str(row)].value  # D列獎項
 30             rewards = ['一等獎', '二等獎', '三等獎', '成功參與獎']
 31             for k in sheet_col:
 32                 university = self.sheet[k + str(row)].value  # 每列大學的名稱
 33                 # team = self.sheet['C' + str(row)].value  # C列隊伍
 34                 # 確定鍵值
 35                 self.universityData.setdefault(university, {})
 36                 for reward in rewards:
 37                     if reward == rewardcell:
 38                         self.universityData[university].setdefault(rewardcell, {'team': 0, 'num': 0})
 39                         self.universityData[university][rewardcell]['num'] += 1  # 統計各個獎項的所有人數
 40                     else:
 41                         self.universityData[university].setdefault(reward, {'team': 0, 'num': 0})
 42 
 43                 if k == 'F':
 44                     self.universityData[university][rewardcell]['team'] += 1  # 只統計隊長所在大學
 45         self.universityData = sorted(self.universityData.items(), key=lambda item: item[0])  # 按照鍵值排序返回元祖
 46         self.universityData = dict(self.universityData)  # 將元祖轉換成字典
 47         total_sum.append(self.universityData)
 48         # total_sum[str(self.new_sheet.title)] = self.universityData  # 在字典total_sum中添加新的鍵,每個表單的字典作為值進行存儲
 49         # print('universityData', self.universityData)
 50         # print(type(self.universityData))
 51         return self.universityData, total_sum
 52 
 53     # 查找單個鍵
 54     def find(self, target, dictData, notFound='沒找到'):
 55         # 倒序查找第一個出現的需要查找的鍵的值
 56         queue = [dictData]  # 將字典存入列表
 57         while len(queue) > 0:
 58             data = queue.pop()  # data是在queue中取出的最后一個元素,也就是原始字典;此時的queue為空列表[]
 59             print('data', data)
 60             for key, value in data.items():
 61                 if key == target:
 62                     return value
 63                 elif type(value) == dict:
 64                     queue.append(value)
 65         return notFound
 66 
 67     # 有多個同名鍵在字典里時,可以用這個方法
 68     def findAll(self, target, dictData, notFound=None):
 69         # 倒序查找所有出現的需要查找的鍵的值
 70         if notFound is None:
 71             notFound = []
 72         queue = [dictData]
 73         result = []
 74         while len(queue) > 0:
 75             data = queue.pop()
 76             for key, value in data.items():
 77                 if key == target:
 78                     result.append(value)
 79                 elif type(value) == dict:
 80                     queue.append(value)
 81         if not result: result = notFound
 82         return result
 83 
 84     def write_list_to_excel(self, dictData, num_list, team_list):
 85         list_slice = []  # 人數切片
 86         team_slice = []  # 隊伍切片
 87         sublist_sum = []  # 每個人數切片的和
 88         team_sum = []  # 每個隊伍切片的和
 89         k = 0
 90         row_1 = ['學校名稱','一等獎','二等獎','三等獎','成功參與獎','總人數','隊伍數量']
 91         for i in range(len(row_1)):
 92             self.new_sheet.cell(row=1,column=i+1,value=row_1[i])
 93         university_name = []
 94         for key in dictData.keys():
 95             university_name.append(key)
 96         for index, name in enumerate(university_name):
 97             self.new_sheet['A'+str(index+2)] = name
 98         while k < len(num_list):
 99             sub_list = num_list[k:k+4]  # 人數子集
100             team_sub = team_list[k:k+4]  # 隊伍子集
101             list_slice.append(sub_list)  # 切片后存入列表
102             team_slice.append(team_sub)
103             sumlist = sum(sub_list)  # 計算每個子集的和
104             teamsum = sum(team_sub)
105             sublist_sum.append(sumlist)  # 將每個子集的和加入列表
106             team_sum.append(teamsum)
107             k += 4
108             if k > len(num_list):
109                 break
110         for row in range(2, len(university_name)+2):
111             for col in range(2, 6):
112                 self.new_sheet.cell(column=col, row=row, value=list_slice[row-2][col-2])
113             self.new_sheet.cell(column=6, row=row, value=sublist_sum[row-2])
114             self.new_sheet.cell(column=7, row=row, value=team_sum[row - 2])
115         return university_name, list_slice, sublist_sum, team_sum
116 
117 
118 class TotalData(ExceltoExcel):
119     def __init__(self):
120         super(TotalData,self).__init__(file, new_sheet)
121         self.sheet_summary = wb_new['Sheet']  # 獲取要寫入的表單
122 
123     def sum(self, totalsum):
124         keys = []  # 包含6個字典中所有的鍵
125         # alldata = []  # 每個大學在所有表單中的獲獎情況
126         all_num = []  # 每個大學所有獲獎人數的總和
127         all_team = []  # 每個大學所有獲獎隊伍總數,只統計隊長所在的隊伍
128         row_1 = ['學校名稱', '獲獎人數', '獲獎隊伍數']
129         for i in range(len(row_1)):
130             self.sheet_summary.cell(row=1,column=i+1,value=row_1[i])
131         for elements in totalsum:  # 循環遍歷每個表單字典
132             for element in elements.keys():
133                 # keys()方法返回包含所有鍵的列表,values()方法返回所有值的列表,.items()方法返回包含鍵值對的元祖
134                 keys.append(element)  # 鍵為每個大學的名稱,keys中包含所有表單所有大學的名稱
135         all_key = list(set(keys))  # 去除列表中的重復元素
136         all_key.sort()
137         # print('all_key', all_key)
138         for key in all_key:
139             # print('key', key)
140             one_num = []  # 用來存儲每一個大學每個賽題的獲獎人數總和
141             one_team = []  # 用來存儲每一個大學每個賽題的獲獎隊伍總和
142             # i為要查找的鍵,此處是大學名稱,在全部的大字典中查找大學,列出每個表單中同一個大學對應的在6個賽題中的獲獎情況
143             # print('self.totalsum1', self.totalsum)
144             result_in_alldata = self.findAll(key, list_to_dict(totalsum))
145             result_in_alldata.reverse()
146             # print('alldata', result_in_alldata)
147             # alldata.append(result_in_alldata)
148             for data in result_in_alldata:  # 依次遍歷每道題的獲獎情況
149                 # print('data', data)
150                 num = self.findAll('num', data)  # 每一個大學在每一個賽題的每一個獎項的獲獎人數
151                 num.reverse()
152                 # print('num', num)
153                 team = self.findAll('team', data)  # 每一個大學在每一個賽題的每一個獎項的獲獎隊伍數
154                 team.reverse()
155                 one_num.append(sum(num))  # 每個賽題的獲獎人數總和
156                 one_team.append(sum(team))
157             all_num.append(sum(one_num))  # 每個大學所有獲獎人數總和
158             all_team.append(sum(one_team))
159         for row in range(2, len(all_key)+2):
160             self.sheet_summary.cell(column=1, row=row, value=all_key[row - 2])
161             self.sheet_summary.cell(column=2, row=row, value=all_num[row - 2])
162             self.sheet_summary.cell(column=3, row=row, value=all_team[row - 2])
163 
164         return all_key, all_num, all_team
165 
166 
167 def list_to_dict(total_list):
168     new_total_dict = {}
169     for index, dic in enumerate(total_list):
170         new_total_dict[index+1] = dic
171     return new_total_dict
172 
173 
174 if __name__ == '__main__':
175     file_path = './file'  # excel文件路徑
176     files = []  # 存儲excel文件名
177     list1 = os.listdir(file_path)  # 列出excel文件路徑下所有的文件
178     list1.sort(key=lambda x: x[4:5])  # 按照題目順序排序
179     total_sum = []
180     # print('list', list)
181     for i in range(len(list1)):
182         item = os.path.join(file_path, list1[i])
183         files.append(item)
184     # print('files', files)
185     wb_new = openpyxl.Workbook()  # 新建一個表格來存儲生成的數據
186     f = open('result.txt', 'w')
187     for k,file in enumerate(files):
188         new_sheet = wb_new.create_sheet('list', index=k)  # 插入新表單
189         excel = ExceltoExcel(file, new_sheet)
190         dictData, total_sum = excel.excel_to_dict()  # 得到當前表格排序后的字典
191         # find_one = excel1.find('team', dictData)
192         find_num = excel.findAll('num', dictData)  # 查找當前表格每個大學每個獎項的獲獎人數
193         find_team = excel.findAll('team', dictData)  # # 查找當前表格每個大學每個獎項的獲獎隊伍數,只統計隊長所在的學校
194         find_num.reverse()  # 正序排列
195         find_team.reverse()  # 正序排列
196         _, _, _, team_sum = excel.write_list_to_excel(dictData,find_num, find_team)
197         wb_new.save('result.xlsx')
198         # print('university name', university)
199         # print('list_slice', list_slice)
200         # print('sublist_sum', sublist_sum)
201         title = file.split('/')[2][4:5]  # 字符串分割提取題目,原標題為'./file/2019A.xlsx'
202         print('{}題共有{}支隊伍獲獎'.format(title, sum(team_sum)))
203         f.write('{}題共有{}支隊伍獲獎\n'.format(title, sum(team_sum)))
204     # print('total_sum', total_sum)
205     total_data = TotalData()  # total_sum是包含每個表格的所有字典即總共6個字典的列表
206     all_university, num, team = total_data.sum(total_sum)
207     print('2019年數學建模比賽共有{}所大學參加,獲獎總人數為{},獲獎隊伍為{}'.format(len(all_university),sum(num),sum(team)))
208     f.write('2019年數學建模比賽共有{}所大學參加,獲獎總人數為{},獲獎隊伍為{}'.format(len(all_university),sum(num),sum(team)))
209     wb_new.save('result.xlsx')

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM