讀Python數據分析基礎之Excel讀寫與處理
- 2019 年 10 月 8 日
- 筆記
對於業務型數據分析來說,Excel可以說是打交道最多的軟件了,可以說沒有之一。之前有比較系統地讀過《Python數據分析基礎》(Foundations for Analysis with Python),寫了一些筆記,這裡只選取關於Excel的部分。
這篇筆記不是講各類Excel函數和快捷鍵,而是講Python對Excel的 .xls 和 .xlsx 格式數據的讀寫和處理。《Python數據分析基礎》第82頁說:
Excel 是商業活動中不可或缺的工具,所以知道如何使用 Python 處理 Excel 數據可以使 你將 Python 加入到數據處理工作流中,進而從其他人那裡接收數據,並以他們習慣接受的 方式分享數據處理結果。
目錄
- Excel文件簡介
- Excel文件的讀取
- Excel文件的寫入
- pandas庫讀寫Excel
- 篩選與統計量計算
Excel文件簡介
Excel其實相信大家都不陌生,一個 .xls(Excel 2013後默認格式為 .xlsx )文件是一個工作簿(workbook),包含多個表(worksheet),每個表內數據按照行列進行組織,書中第三章的用詞中,「文件」和「工作簿」表示同一個對象。拿本篇筆記用到的示例文件 sales_2015.xlsx 為例:

workbookAndWorkSheets
本篇筆記需要用到兩個庫: xlrd 和 xlwt,這兩個庫不是內置模塊,但安裝了Anaconda集成環境的話,這兩個庫被包含了,可以通過 import xlrd 和 import xlwt 進行測試,如果提示未安裝,可以通過命令行下用pip安裝,本處不展開。xlrd用來讀取Excel文件,xlwt用於構建Workbook對象進行Excel文件的創建和寫入數據。這兩個庫不能對Excel文件進行直接更改,因此思路是複製一份數據到內存進行分析計算,再寫入新Excel文件中。需要直接性地修改可以考慮VBA吧,VBA(Visual Basic for Applications)是目前 Office 套件支持的基於 Visual Basic 的宏語言,目前一般在Excel或PPT內進行編程實現高級效果(如Excel數據的批量修改)一般都用VBA,當然以後Office要內置Python了,現在學好Python以後就能很容易理解和定製化Excel的宏了。
Excel文件的讀取
通過xlrd庫的open_workbook()對Excel數據進行讀入。
#lrd讀取並輸出基本信息# -*- coding: utf-8 -*-def readExcel(fname): from xlrd import open_workbook workbook = open_workbook(fname) print('工作表數量:', workbook.nsheets) for worksheet in workbook.sheets(): #循環輸出表名 print("Worksheet name:", worksheet.name, "tRows:",worksheet.nrows, "tColumns:", worksheet.ncols) readExcel('sales_2015.xlsx')
輸出:
工作表數量: 3 Worksheet name: january_2015 Rows: 7 Columns: 5 Worksheet name: february_2015 Rows: 7 Columns: 5 Worksheet name: march_2015 Rows: 7 Columns: 5
Excel文件的寫入
寫入要用到 xlwt 庫,如下面的代碼,創建一個Workbook對象後,通過worksheet.write()寫入數據。因為使用with進行處理,所以不需要寫close()顯式關閉打開的文件。
#讀取一些Excel並寫入新表def parsingExcToWrite(in_file,out_file): from xlrd import open_workbook from xlwt import Workbook #導入一個 Workbook對象 output_workbook = Workbook() output_worksheet = output_workbook.add_sheet('jan_2015_output') #加一個新工作表到工作簿對象里 with open_workbook(in_file) as workbook: worksheet = workbook.sheet_by_name('january_2015') #引用上面創建的工作表 print('type(worksheet):',type(worksheet)) print('write()傳入參數類型:',type(worksheet.cell_value)) for row_index in range(worksheet.nrows): for column_index in range(worksheet.ncols): #枚舉寫入數據 output_worksheet.write(row_index, column_index, worksheet.cell_value(row_index, column_index)) output_workbook.save(out_file) in_f='sales_2015.xlsx'out_f='save_sales_2015.xlsx'parsingExcToWrite(in_f,out_f) #調用
輸出:
type(worksheet): <class 'xlrd.sheet.Sheet'>write()傳入參數類型: <class 'method'>
生成的文件效果如下:

save_sales_by_xlwt
上面寫成的函數parsingExcToWrite()就是是一個可以使用在讀取、處理、寫入的框架,如前所說,這兩個庫不能直接對Excel進行修改,那麼讀取相應的數據處理後再寫入新表就是很好的解決方案。 下面的處理代碼如果需要保存處理後的數據就可以基於這段代碼進行擴展。
pandas庫讀寫Excel
下面看看用pandas進行Excel讀取的操作, 讀只需要一句話(引入庫的不算在內),pd.read_excel(in_fname),和前一篇筆記讀取csv的格式一樣,都是生成dataframe數據格式。寫入Excel通過pd.ExcelWriter()構建一個Excel寫入對象,再對這個對象操作,最後調用 .save()進行寫入到硬盤。
import pandas as pd in_f='sales_2015.xlsx'out_f='save_sales_2015_1.xlsx'data_frame = pd.read_excel(in_f, 'january_2015', index_col=None) #對 data_frame進行一些處理dframe_condition = data_frame[:] writer = pd.ExcelWriter(out_f) dframe_condition.to_excel(writer, sheet_name='sheet_name',index=False) writer.save() print('done')#輸出: done
篩選與統計量計算
因為pandas可以簡化一些操作,並且多練pandas是很有意義很重要的,所以下面篩選和統計量的計算都是基於pandas的處理。
有些時候,我們並不需要 Excel 文件中的所有行,特別是數據量很大但是我們只關心滿足一定條件的數據。例如,可能只需要包含一個特定的詞數值的那些行,或者只需要那些與一個具體日期相關聯的行數據。這時候我們就需要進行篩選,去掉不需要的行,只保留需要的行。
下面的代碼演示了篩選 Sale Amount 大於 $567.00 的行。我們可以通過改變代碼data_frame_value_meets_condition = data_frame[data_frame['Sale Amount'].astype(float) > 567.0] 來篩選行中的值滿足某個條件的數據。
#import pandas as pd #上面引入了這裡就不需要重複引入,如果是獨立的文件需要寫上這句def valConditionExc(in_file,out_file): data_frame = pd.read_excel(in_file, 'january_2015', index_col=None) data_frame_value_meets_condition = data_frame[data_frame['Sale Amount'].astype(float) > 567.0] writer = pd.ExcelWriter(out_file) data_frame_value_meets_condition.to_excel(writer, sheet_name='jan_15_output',index=False) writer.save()#行中的值匹配於特定模式def valMatchPattern(in_file,out_file): data_frame = pd.read_excel(in_file, 'january_2015', index_col=None) df_value_matp = data_frame[data_frame['Customer Name'].str.startswith("J")] writer = pd.ExcelWriter(out_file) df_value_matp.to_excel(writer, sheet_name='jan_15_output',index=False) writer.save() print(df_value_matp)#選擇滿足一定條件的特定列數據def selectColByIndex(in_file,out_file): data_frame = pd.read_excel(input_file, 'january_2015', index_col=None) df_col_by_index = data_frame.iloc[:, [1, 4]] writer = pd.ExcelWriter(output_file) df_col_by_index.to_excel(writer, sheet_name='jan_15_output',index=False) writer.save()in_f='sales_2015.xlsx'valConditionExc(in_f,'save_sales_2015_2.xlsx') valMatchPattern(in_f,'save_sales_2015_3.xlsx')
輸出:
Customer ID Customer Name Invoice Number Sale Amount Purchase Date0 1234 John Smith 100-0002 123 2015-01-014 5678 Jenny Walters 100-0006 345 2015-01-24
使用 pandas 基於列標題選取特定列,一種方式是在數據框名稱後面的方括號中將列名以字符串方式列出。另外一種方式是使用 loc 函數。如果使用 loc 函數,那麼需要在列標題列表前面加上一個冒號和一個逗號,表示你想為這些特定的列保留所有行。例如下面的代碼:
#import pandas as pd def selectAllColByName(in_file,out_file): data_frame = pd.read_excel(in_file, 'january_2015', index_col=None) selected_columns = data_frame.loc[:, ['Customer ID', 'Purchase Date']] #根據列標題選取特定列 writer = pd.ExcelWriter(out_file) selected_columns.to_excel(writer, sheet_name='jan_13_output',index=False) print(selected_columns) writer.save() in_f='sales_2015.xlsx'selectAllColByName(in_f,'save_sales_2015_4.xlsx')
輸出:
Customer ID Purchase Date0 1234 2015-01-011 2345 2015-01-062 3456 2015-01-113 4567 2015-01-184 5678 2015-01-245 6789 2015-01-31
大家可以根據代碼的效果區分上上部分代碼的data_frame.iloc[:, [1, 4]] 和上面的data_frame.loc[:, ['Customer ID', 'Purchase Date']]
.loc for label based indexing .iloc for positional indexing
數據裝入pandas的dataframe之後,除了進行篩選,計算一些統計量也是數據分析很重要的工作,描述性統計給我們提供了很多描述數據的指標,下面的代碼為工作表的銷售數據計算總數和均值。
#import pandas as pd def getSumAndAverage(in_f): all_worksheets = pd.read_excel(in_f,sheetname=None, index_col=None) workbook_total_sales = [] workbook_number_of_sales = [] workbook_mean_sales = [] for worksheet_name, w_data in all_worksheets.items(): total_sales = pd.DataFrame([float(str(value).strip('$').replace(',','')) for value in w_data.loc[:, 'Sale Amount']]).sum() #算一個表的總體銷售額 number_of_sales = len(w_data.loc[:, 'Sale Amount']) workbook_total_sales.append(total_sales) #裝入一個列表 workbook_number_of_sales.append(number_of_sales) mean_sales=total_sales/number_of_sales #均值 workbook_mean_sales.append(mean_sales) print(worksheet_name,'t total:',total_sales[0],'t num:',number_of_sales,'t mean:',mean_sales[0]) in_f='sales_2015.xlsx'getSumAndAverage(in_f)
輸出:
january_2015 total: 3201.0 num: 6 mean: 533.5february_2015 total: 55007.0 num: 6 mean: 9167.83333333march_2015 total: 246045.0 num: 6 mean: 41007.5
《Python數據分析基礎》第三章講了Excel文件的讀寫和處理,裏面提供了xlrd、xlwt進行讀寫處理以及對應的pandas庫進行讀寫和處理,本篇筆記基本覆蓋了第三章的重點內容,縮減了一些例子,在處理的部分都是用pandas庫進行,書中還提供了xlrd、xlwt進行處理的代碼,代碼比較長,需要理解這部分內容請閱讀原書。下一章進入數據庫的內容,數據庫也是數據分析師經常要操作的工具。之後在可視化部分中還會經常用到pandas,讀取數據後進行可視化是很美好的事。
