昨天介紹Pandas的資料操作,當index沒有對應到的時候會出現NaN,今天要來介紹Pandas中如果資料是空值(或者沒有)時可以採取的資料型態。昨天也介紹Pandas資料型態和Numpy不同的是會有index,可是昨天示範都只有單一的index,今天的內容一部分也會講MultiIndex。

今天學習得的重點

  • 處理Pandas中缺失的資料
  • MultiIndex
  • Pandas缺失的資料

  • None:是一種object
  • import numpy as np
    import pandas as pd
    ironman = np.array([1,None,3,4])
    ironman
    
    # 輸出結果
    array([1, None, 3, 4], dtype=object)
    

    None在數值運算中會出現錯誤,ex: sum(),min(),因此出現了NaN這樣的數值缺失資料型態

  • NaN:特殊浮點數數值
  • ironman = np.array([1,np.nan,3,4])
    ironman.dtype
    
    # 輸出結果
    dtype('float64')
    

    使用NaN進行數值運算
    sum()改成用nansum(), min()改成用nanmin(), max()改成用nanmax()

    np.nansum(ironman),np.nanmin(ironman),np.nanmax(ironman)
    
    # 輸出結果
    (8.0, 1.0, 4.0)
    

    Null的操作

    isnull():檢查空值,回傳布林值
    notnull():檢查不是空值,回傳布林值
    dropna():刪除空值
    fillna():填入空值

    ironman = pd.Series([1,np.nan,3,4,None])
    ironman.isnull()
    
    #輸出結果
    0    False
    1     True
    2    False
    3    False
    4     True
    dtype: bool
    

    notnull和遮罩一起的應用,取出陣列中不是空值的部分

    ironman[ironman.notnull()]
    
    # 輸出結果
    0    1.0
    2    3.0
    3    4.0
    dtype: float64
    

    示範刪除DataFrame空值,會直接刪除整欄和整列

    ironman = pd.DataFrame([
        [1,np.nan,3],
        [4,5,6],
        [7,8,np.nan]])
    ironman.dropna()
    
    # 輸出結果
    	0	1	 2
    1	4	5.0	 6.0
    

    示範將null填入0

    ironman = pd.Series([1,np.nan,3,4,None])
    ironman.fillna(0)
    
    # 輸出結果
    0    1.0
    1    0.0
    2    3.0
    3    4.0
    4    0.0
    dtype: float64
    

    MultiIndex

  • 建立一個MultiIndex,使用from_tuples
  • index = [('Taichung',2018),('Taichung',2017),
             ('Changhua',2018),('Changhua',2017),
             ('Taipei',2018),('Taipei',2017),
             ('Kaohsiung',2018),('Kaohsiung',2017)]
    index = pd.MultiIndex.from_tuples(index)
    index
    
    # 輸出結果
    MultiIndex(levels=[['Changhua', 'Kaohsiung', 'Taichung', 'Taipei'], [2017, 2018]],
               labels=[[2, 2, 0, 0, 3, 3, 1, 1], [1, 0, 1, 0, 1, 0, 1, 0]])
    
  • 用MultiIndex建立Series
  • elementary = [
        800,780,
        620,580,
        1500,1350,
        1100,998
    ironman = pd.Series(elementary, index=index)
    ironman
    
    # 輸出結果
    Taichung   2018     800
               2017     780
    Changhua   2018     620
               2017     580
    Taipei     2018    1500
               2017    1350
    Kaohsiung  2018    1100
               2017     998
    dtype: int64
    

    用MultiIndex取得資料,所有2017年國小數

    ironman[:,2017]
    
    #輸出結果
    Taichung      780
    Changhua      580
    Taipei       1350
    Kaohsiung     998
    dtype: int64
    

    其他取得資料的方式

    ironman[ironman > 600]               #遮罩
    ironman[['Changhua','Kaohsiung']]    #fancy索引
    
  • MultiIndex和DataFrame之間做轉換
    unstack(): MultiIndex->DataFrame
    stack(): DataFrame->MultiIndex
  • ironman_unstack = ironman.unstack()
    ironman_unstack
    
    # 輸出結果
    	        2017	2018
    Changhua	580	    620
    Kaohsiung	998	    1100
    Taichung	780	    800
    Taipei	    1350	1500
    
  • 將MultiIndex的index給予名稱
  • ironman.index.names = ['area','year']
    ironman
    
    # 輸出結果
    area       year
    Taichung   2018     800
               2017     780
    Changhua   2018     620
               2017     580
    Taipei     2018    1500
               2017    1350
    Kaohsiung  2018    1100
               2017     998
    dtype: int64
    
  • 以下示範column的index
  • ironmanIndex = pd.MultiIndex.from_product([[2017, 2016, 2018], [1, 2]],names=['year','enroll'])
    ironmanColumns = pd.MultiIndex.from_product([['azure','ai&data','web'], ['自我挑戰組', '主題競賽']],names=['subject','type'])
    number = np.random.randint(50, size=(6,6))
    ironmanNumber = pd.DataFrame(number, index = ironmanIndex, columns=ironmanColumns )
    ironmanNumber
    
    # 輸出結果
    	subject	             azure	             ai&data	                web
        type	    自我挑戰組  主題競賽	  自我挑戰組	主題競賽  自我挑戰組	主題競賽
        year  enroll						
        2017	1	    44	      6	         6	      33	     29	      6
                2	    3	      24	    14	       7	      9	      0
        2016	1	    45	      18	    10	      36	     43	     27
                2	    42	      23	    44	      21	     17	     34
        2018	1	    29	      22	    42	      29	      4	     12
                2	    6	      5	        31	       9	     48	      4
    
  • order MultiIndex
    用上述的ironmanNumber當例子,排序year
  • ironmanNumber.sort_index()
    
    # 輸出結果
    	subject	             azure	             ai&data	                web
        type	    自我挑戰組  主題競賽	  自我挑戰組	主題競賽	自我挑戰組	主題競賽
        year  enroll	
        2016	1	    45	      18	    10	      36	       43	     27
                2	    42	      23	    44	      21	       17	     34
        2017	1	    44	      6	         6	      33	       29	      6
                2	    3	      24	    14	       7	        9	      0
        2018	1	    29	      22	    42	      29	        4	     12
                2	    6	      5	        31	       9	       48	      4
    

    *sum(),mean(), max() on MultiIndex
    用ironmanNumber來取得每年參加的組數平均

    ironmanNumber.mean(level='year')
    
    # 輸出結果
    	subject	             azure	             ai&data	                web
        type	    自我挑戰組  主題競賽	  自我挑戰組	主題競賽  自我挑戰組	主題競賽
        2017	        23.5	15.0	      10.0	 20.0	    19.0	  3.0
        2016	        43.5	20.5	      27.0	 28.5	    30.0	 30.5
        2018	        17.5	13.5	      36.5	 19.0	    26.0	  8.0
    安裝Anaconda
    安裝Jupyter notebook
    
  • Numpy create Numpy min、max、broadcasting、運算子 Fancy、sort、structured array
  • Pandas Series、DataFrame、Index
  • 程式碼位置 github
    因為作者本身也是第一次學習Python和寫程式文章,所以編排上會有點亂,觀念可能也會錯誤,如果有疑問可以提出一起討論,等30天完成之後有其他時間會將之前寫的文章加入一些想法。
  •