尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️
數據收集、清洗、整理與數據可視化是Python數據處理的第一步,本練習通過一個實際的數據集(加拿大移民人口數據),對Pandas,Matplotlib庫進行基本講解。主要的數據可視化在python下依賴matplotlib和pandas,如果已經安裝了Anaconda發行版,則這兩個庫默認都已經安裝,如果只是安裝Jupyter Notebook,則可以直接通過命令行命令進行安裝。
!pip install pandas !pip install matplotlib
1. 數據集引入
示例數據集來自加拿大官方移民數據,數據年限僅截止到2013年。首先,需要導入numpy和pandas兩個庫,對數據進行基本分析。因為數據是excel格式的(這是最廣泛的數據格式之一,還需要安裝xlrd庫),在Anaconda和標準Python發行版下通過下列兩個命令可以分別做到安裝。
!pip install xlrd !conda install -c anaconda xlrd --yes
需要注意的一點是,在Jupyter Notebook中安裝包之後,內核可能不能馬上導入使用,可以點擊Kernel菜單下的Restart選項重新啟動Kernel就可以恢復正常。
import numpy as np # useful for many scientific computing in Python import pandas as pd # primary data structure library
讀取示例數據並顯示頭/尾。
df_can = pd.read_excel('https://ibm.box.com/shared/static/lw190pt9zpy5bd1ptyg2aw15awomz9pu.xlsx', sheet_name='Canada by Citizenship', skiprows=range(20), skipfooter=2) print ('Data read into a pandas dataframe!') df_can.head() # tip: 如果需要顯示更多行可以指定數據,比如 df_can.head(10)
5 rows × 43 columns
df_can.tail()
5 rows × 43 columns
其他基本的查詢指令,可以參考pandas的API文檔。
df_can.info() df_can.columns.values df_can.index.values print(type(df_can.columns)) print(type(df_can.index)) df_can.columns.tolist() df_can.index.tolist() print (type(df_can.columns.tolist())) print (type(df_can.index.tolist())) # size of dataframe (rows, columns) df_can.shape (195, 43)
數據清洗與整理
對數據集需要做一些基本的清洗與整理,下列幾個步驟分別去掉不需要的列,對部分列重新命名使得更具有可讀性,並增加了一個匯總列。
# in pandas axis=0 represents rows (default) and axis=1 represents columns. df_can.drop(['AREA','REG','DEV','Type','Coverage'], axis=1, inplace=True) df_can.head(2)
2 rows × 38 columns
df_can.rename(columns={'OdName':'Country', 'AreaName':'Continent', 'RegName':'Region'}, inplace=True) df_can.columns Index([ 'Country', 'Continent', 'Region', 'DevName', 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013], dtype='object') df_can['Total'] = df_can.sum(axis=1) df_can.isnull().sum()
2. Pandas中級功能,索引與選擇
先看看當下的數據集信息,然後通過練習熟悉各種索引的使用方式。
df_can.describe()
8 rows × 35 columns
df_can.Country # 查找並返回所有國家列表 df_can[['Country', 1980, 1981, 1982, 1983, 1984, 1985]] # 返回特定年份的值 # 需要注意,國家名稱是字符串類型而年份是整型 # 為了保證格式統一,可以將所有名稱均改為整型
195 rows × 7 columns
df_can.set_index('Country', inplace=True) # 將國家設置為索引項,與之相反的操作是 df_can.reset_index() df_can.head(3)
3 rows × 38 columns
# 也可以去掉索引項的名稱 df_can.index.name = None # 1. 顯示日本籍移民(所有列) print(df_can.loc['Japan']) # 其他做到方式 print(df_can.iloc[87]) print(df_can[df_can.index == 'Japan'].T.squeeze()) # 2. 2013年的數據 print(df_can.loc['Japan', 2013]) # 其他做到方式 print(df_can.iloc[87, 36]) # 2013年是最後一列,總共36列 982 982 # 3. 1980到1985年間的數據 print(df_can.loc['Japan', [1980, 1981, 1982, 1983, 1984, 1984]]) print(df_can.iloc[87, [3, 4, 5, 6, 7, 8]]) 1980 701 1981 756 1982 598 1983 309 1984 246 1984 246 Name: Japan, dtype: object 1980 701 1981 756 1982 598 1983 309 1984 246 1985 198 Name: Japan, dtype: object df_can.columns = list(map(str, df_can.columns)) # [print (type(x)) for x in df_can.columns.values] #<-- 檢查是否正確,去掉前面的註釋就可以運行 # 將要顯示的年份轉換為years列表,在後面顯示圖形時比較實用 years = list(map(str, range(1980, 2014))) years # 1. 通過判斷創建布爾量序列 condition = df_can['Continent'] == 'Asia' print (condition) # 2. 將布爾序列傳給數據集 df_can[condition]
49 rows × 38 columns
# 可以通過多個條件進行篩選 # l比如同時選擇 AreaNAme = Asia 和RegName = Southern Asia df_can[(df_can['Continent']=='Asia') & (df_can['Region']=='Southern Asia')] # 在使用邏輯操作符時, 需要用 '&' 和 '|' 取代 'and' 和 'or' # 不同條件需要分別通過括號分開。
9 rows × 38 columns
print ('data dimensions:', df_can.shape) print(df_can.columns) df_can.head(2) data dimensions: (195, 38) Index(['Continent', 'Region', 'DevName', '1980', '1981', '1982', '1983', '1984', '1985', '1986', '1987', '1988', '1989', '1990', '1991', '1992', '1993', '1994', '1995', '1996', '1997', '1998', '1999', '2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '2011', '2012', '2013', 'Total'], dtype='object')
2 rows × 38 columns
3. 使用Matplotlib用以做到數據可視化
# %是Jupyter Notebook的魔術命令,這里使用inline即在文件中顯示內容 %matplotlib inline import matplotlib as mpl import matplotlib.pyplot as plt print ('Matplotlib version: ', mpl.__version__) # >= 2.0.0 版本要大於2.0.0 Matplotlib version: 3.0.2 print(plt.style.available) mpl.style.use(['ggplot']) # optional: for ggplot-like style ['bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark-palette', 'seaborn-dark', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'seaborn', 'Solarize_Light2', 'tableau-colorblind10', '_classic_test'] haiti = df_can.loc['Haiti', years] # years參數見前節passing in years 1980 - 2013 to exclude the 'total' column haiti.head() 1980 1666 1981 3692 1982 3498 1983 2860 1984 1418 Name: Haiti, dtype: object haiti.plot() haiti.index = haiti.index.map(int) # 將海地的索引項改為整數以顯示年份 haiti.plot(kind='line') plt.title('Immigration from Haiti') plt.ylabel('Number of immigrants') plt.xlabel('Years') plt.show() # 本行用以顯示圖形
haiti.plot(kind='line') #可以在圖形中添加標籤 plt.title('Immigration from Haiti') plt.ylabel('Number of Immigrants') plt.xlabel('Years') # 也可以在指定位置插入數據 # syntax: plt.text(x, y, label) plt.text(2000, 6000, '2010 Earthquake') # see note below plt.show()
以下程序用以顯示中國和印度籍移民圖示
df_CI=df_can.loc[['China','India'],years] df_CI.head()
1980198119821983198419851986198719881989…2004200520062007200820092010201120122013China5123668233081863152718161960264327584323…36619425843351827642300372962230391285023302434129India8880867081477338570442117150101891152210343…28235362103384828742282612945634235275093093333087
2 rows × 34 columns
df_CI.plot(kind='line') <matplotlib.axes._subplots.AxesSubplot at 0x56c6d90>
上述的圖形顯然有問題,這主要是因為橫軸縱軸錯誤,這是個常見的問題,需要通過transpose方法先修正。
df_CI = df_CI.transpose() df_CI.head()
ChinaIndia198051238880198166828670198233088147198318637338198415275704
df_CI.index = df_CI.index.map(int) df_CI.plot(kind='line') plt.title('Immigration from China and India') plt.ylabel('Number of Immigrants') plt.xlabel('Years') # annotate the 2010 Earthquake. # syntax: plt.text(x, y, label) plt.show()
df_can.sort_values(by='Total', ascending=False, axis=0, inplace=True) df_top5 = df_can.head(5) df_top5 = df_top5[years].transpose() print(df_top5) India China United Kingdom of Great Britain and Northern Ireland \ 1980 8880 5123 22045 1981 8670 6682 24796 1982 8147 3308 20620 1983 7338 1863 10015 1984 5704 1527 10170 1985 4211 1816 9564 1986 7150 1960 9470 1987 10189 2643 21337 1988 11522 2758 27359 1989 10343 4323 23795 1990 12041 8076 31668 1991 13734 14255 23380 1992 13673 10846 34123 1993 21496 9817 33720 1994 18620 13128 39231 1995 18489 14398 30145 1996 23859 19415 29322 1997 22268 20475 22965 1998 17241 21049 10367 1999 18974 30069 7045 2000 28572 35529 8840 2001 31223 36434 11728 2002 31889 31961 8046 2003 27155 36439 6797 2004 28235 36619 7533 2005 36210 42584 7258 2006 33848 33518 7140 2007 28742 27642 8216 2008 28261 30037 8979 2009 29456 29622 8876 2010 34235 30391 8724 2011 27509 28502 6204 2012 30933 33024 6195 2013 33087 34129 5827 Philippines Pakistan 1980 6051 978 1981 5921 972 1982 5249 1201 1983 4562 900 1984 3801 668 1985 3150 514 1986 4166 691 1987 7360 1072 1988 8639 1334 1989 11865 2261 1990 12509 2470 1991 12718 3079 1992 13670 4071 1993 20479 4777 1994 19532 4666 1995 15864 4994 1996 13692 9125 1997 11549 13073 1998 8735 9068 1999 9734 9979 2000 10763 15400 2001 13836 16708 2002 11707 15110 2003 12758 13205 2004 14004 13399 2005 18139 14314 2006 18400 13127 2007 19837 10124 2008 24887 8994 2009 28573 7217 2010 38617 6811 2011 36765 7468 2012 34315 11227 2013 29544 12603 df_top5.index = df_top5.index.map(int) # let's change the index values of df_top5 to type integer for plotting df_top5.plot(kind='line', figsize=(14, 8)) # pass a tuple (x, y) size plt.title('Immigration Trend of Top 5 Countries') plt.ylabel('Number of Immigrants') plt.xlabel('Years') plt.show()