iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
0
AI & Data

python 入門到分析股市系列 第 11

[Day11]Learning Pandas - 處理空值的資料和使用多重index

前言

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

今天學習得的重點

  1. 處理Pandas中缺失的資料
  2. 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	    自我挑戰組  主題競賽	  自我挑戰組	主題競賽  自我挑戰組	主題競賽
    year	
    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

導讀


上一篇
[Day10]Learning Pandas - Series、DataFrame、Index
下一篇
[Day12]Learning Pandas - 資料合併
系列文
python 入門到分析股市30

尚未有邦友留言

立即登入留言