數據分析其實是一種統計方法,它的特點是多維性和描述性,可以通過數據和圖表揭示不同數據之間的關聯,並進行信息統計,用更簡潔的方式描繪複雜數據所包含的主要信息,這樣就是數據分析的真諦了。
舉個實際例子來說:上司丟給我們一堆數據,其中包含了歷年以來的銷售數據,我們需要從中找出增長規律,客戶的屬性,人員成本等等。
這個過程可能是人工的、手動的,相信有不少讀者在這方面比我更有經驗,上司或老闆要的是報表,我們要的是如何快速準確的按要求出一張報表。
如果數據來源和內容更加複雜,可能分布在不同的文件裡,或者是部分數據還存在於不同的資料庫中,數據內容也不是特別規範的話,那我們就需要用到程式語言對數據進行清洗再進行分析了。
這個教程系列主要講述利用 Python和其相關的組件進行數據分析的工作,主旨是為了讓我們通過本系列的學習掌握Pyhton數據分析的基本思路和方法,學會一些常見分析工具的使用。讓原來需要很長時間才能完成的報表分析工作在更短的時間內完成。
本章知識點:
Python讀寫CSV文件Python讀寫Excel文件關於數據分析的行為,我們每個人對它的理解和認識都不一樣,有人覺得數據分析就是把已有的數據文件(比如Excel) 打開進行查閱,有人覺得數據分析是從資料庫裡按照需求用SQL語句查詢數據,甚至是通過網際網路爬蟲去抓取數據並進行分析。
不過總結起來主要還是對文件進行的讀取,所謂的資料庫也是存儲在文件系統裡,只是中間多封裝了一個結構化的數據層而已。
Python讀取CSV文件
CSV文件也叫逗號分隔值文件(Comma-Separated Values),每一組數據之間通過逗號分割(少部分時候也可以用其他符號分割)CSV文件的特點是以純文本的形式存儲表格數據,因為CSV是純文本的文件,所以我們可以認為它是一個字符序列,不需要像讀取二進位那樣的方式來讀取文件內容。
以下是一個簡單的CSV文件的格式。
我用文本編輯器遍寫了一個CSV文件,命名為三國武將表.csv。
第一行是表頭,用於描述每一列數據的用處,每一列通過逗號分隔。第二行開始連續定義了三個武將的屬性信息,同樣每一列數據都通過逗號分隔。
現在我們可以用Excel或者別的電子表格軟體打開這個CSV文件,看看是它是如何展現數據的。
假設我們在做一個關於三國的遊戲,這個武將表的信息將直接被讀取到內存裡展現到遊戲畫面裡,那麼我們就需要隨時對數據進行修改和保存,現在就需要藉助到Python讀寫CSV文件了。
因為Python標準庫裡自帶了對CSV文件對讀寫支持,所以我們可以直接使用 import csv 來導入CSV文件處理模塊。
詳細代碼和運行結果如下:
通過以上代碼,我們首先import csv這個Python自帶的模塊。
打開本地文件 "三國武將表.csv"設置為變量f。
通過csv.reader()將 f 變量所代表文件對象轉換為csv文件對象 f_csv。
這個時候 f_csv對象其實是一個可迭代對象,我們對其進行for循環即可列印出每一行的內容了,而每一行的內容就是一個list(列表),它由每一列的數據組成,很直觀。
現在有一個新的需求,我們希望對隨機減掉每個武將的血量,讓數據看起來像是剛剛打完一場仗 (呂布此刻正在虎牢關單挑關羽張飛呢)。
現在重新改造一下剛才的代碼實現修改武將血量。
如上圖所示我們實現了武將血量的隨機減少。
在代碼裡我們主要加了一個叫random的Python標準庫,它的主要用處是用來產生隨機數。
在代碼第9行,我們對row的元素下標為2的值隨機減去了一些值,之所以不直接用row[2]而需要用int(row[2])轉換數據為整型數字,原因是CSV文件默認讀取進來都是字符串類型的,如果我們希望某列數據是數字的話就需要在使用時進行數據轉換。
現在我們已經對幾個武將的血量進行了改變,不過武將的數據還在內存中,我們來把信息保存到CSV文件裡。
Python保存CSV文件
以上代碼我們做了很少的改動,首先定了一個rows列表變量,用於存儲武將屬性變動後的數據。
在15行的 rows.append(row) 用於把每條改變的數據新增到 rows裡。
在第19行,我們用 w文件模式打開了一個新的文件 "三國武將列表_2.csv"用於寫一個新的CSV文件。
通過csv.write(f)把文件對象變成csv的模塊對象,然後調用writerows()方法寫入文件信息。
需要注意的是在這段程序裡我用到了一個try except的語法用於異常處理,因為第一行表頭數據中的 row[2]取到的 「血量」 是文字信息,我們是不可能對其進行加減操作的。
當我們預先料到程序會報錯時就可以用try except來處理異常,在except裡寫一個pass表示如果程序報錯了什麼都不用管,跳過即可。(關於Python的異常處理請參考 紙飛機編程的Python基礎教程系列)
現在來看看寫入的CSV文件,會發現每一個武將的血量都產生了變化。
可能有讀者會好奇,我們的f_csv.writerows(rows) 究竟寫的是什麼東西?我們在代碼裡把rows信息列印出來看看。
在第18行,我們print了rows這個變量的信息,會發現它其實就是包含了多個子列表的列表對象。每一個子列表裡包含了多個列的數據。
Python讀取Excel文件
講完了CSV文件的讀寫後再來講講Excel文件。
Excel是微軟在1982年出品的一款電子表格軟體,因為它界面直觀,計算和圖表功能很不錯,再加上在當時市場上幾乎沒有能打的對手,歷經這麼多年後,Excel文件幾乎成為了電子表格的行業標準。
我們需要將Excel文件和Excel軟體區分開,Excel文件格式擴展名一般叫做xls或者xlsx,它可以由微軟的Excel軟體打開編輯,同樣可以被其他的軟體進行編輯,例如WPS、Numbers等等。
現在我們可以把剛才的CSV文件先另存為一個Excel格式的文件吧,因為CSV文件已經在我的電腦裡被Numbers軟體打開了,所以我直接把它另存為xlsx格式的文件即可。
現在就可以得到一個名為 「三國武將表.xlsx的文件"。
那麼如何在 Python裡讀取一個Excel文件呢?
在Python的生態環境裡,提供了大量支持操作Excel文件格式的第三方庫,在本章教程裡,我只用 xlrd 和xlwt 這兩個庫來講解。
通過pip install xlwt xlrd安裝這兩個第三方庫xlrd用於讀取Excel文件xlwt用於寫入Excel文件xlrd讀取Excel文件
以上代碼展示了如何通過xlrd庫讀取一個Excel文件。
首先 import xlrd 引用 xlrd 庫。通過 xlrd.open_workbook()打開一個Excel文件並得到一個xlrd.book.Book 的對象(以下簡稱book對象)。xlrd的 Book 對象有一個 sheets() 的方法,用於得到一個表格文件的所有工作表對象,相信工作表大家在日常工作中都已見過,在這就不再累述了。因為我們在這個表格裡只有一張工作表,所以我們取工作表對象的下標第0個元素即可得到第一張工作表的內容,將其賦值給變量table。在第9行開始遍歷工作表,通過 table.nrows這個屬性獲取表格的行數。通過range(1, 表格行數) 即可獲得一個可遍歷4行的可迭代對象,每次將行號賦值給 rownum 。通過 table.row(rownum)方法可以根據行號得到一行的所有數據(rownum是行號)。我們注意到每一列的數據前面會有一個 text或者 number的文字,它其實是用於區分數據類型究竟是字符串還是數字。
我們講過CSV文件內容都是字符類型的,如果是Excel文件,並且通過xlrd庫讀取的時候,它會自動將數字和字符區隔開,不用我們在處理時進行數據類型轉換。
現在我們同樣對每個武將的血量進行隨機改變,用於學習如何通過Python處理Excel數據。
因為第一行數據是表頭,所以對 rownum 進行判斷,在第2行才開始對血量進行改變。
我們需要在程序裡大量用到每一行數據的對象 table.row(rownum),但是在每一個地方寫這個玩意顯得瑣碎,所以用了一個row_vals存儲每一行數據。
row_vals是每一行數據,通過取元素下標位可以獲得每一列的數據,再訪問其 value 屬性即可獲取每一列的具體內容了 row_vals[2].value。
最後我們看到呂布、關羽、張飛的血量都已經被改變了,而且張飛都快掛了。。。。。。
現在我們來學習如何將數據寫入Excel文件。
xlwt寫入Excel文件
以上代碼解讀如下:
因為我們寫入Excel表需要有至少一個列表對象,並且裡面包含1到多個子列表,每個子列表對應的就是每一行的數據。所以我們在代碼11行定義了一個空的列表 datas,在代碼17行把每一條修改之後對子列表數據通過列表的append()方法把子列表添加到datas裡。在第20行定義了一個xlwt的Workbook對象,設置為變量book,並且在21行調用book對add_sheet()方法添加一張新的工作表,賦值給變量sheet。如果需要在Excel文件裡添加多個工作表,那就需要多做幾次add_sheet()操作分別賦值。最後我們來看看 sheet.write()方法,它接受三個參數,分別是(行號,列號,數據內容)。因為write()每次只能寫入一列數據,所以我們需要明確的告訴它在第幾行,第幾列寫入什麼數據。基於write()的參數要求,我做了一個雙重for循環,第一層for 循環取出 rownum和 val,rownum變量是行號,每一行的數據列表的變量是val,再在下一層循環裡對val進行遍歷,取出列表的元素下標和具體的值,這裡的i和j分別就對應著列號和具體的值了,大家在腦子裡過一遍,模擬一下這個雙重for循環的過程,至於enumerate內置函數的作用就是對一個可迭代對象取值,分別得到其元素下標位和值。最後通過book.save()把表格數據保存為文件為了方便理解數據格式,我們把datas的內容列印出來看看。
通過以上截圖我們可以發現其實datas的內容就是列表裡嵌套了多個子列表,對其進行雙重for循環,盤它就是了。
現在來看看輸出Excel文件結果:
通過對xlrd和xlwt兩個庫的結合使用,我們可以避免很多重複性的勞動,完成更多有趣的工作。
最後我們通過一個思維導圖來總結一下本章的所有知識點。
本章教程到此結束,關於CSV文件和Excel文件其實還有更多的讀寫方法,我們將在以後的章節裡一一講解。
歡迎關注我 「紙飛機編程」,獲取更多有趣的Python編程信息。