數據科學庫pandas筆記3

缺失數據的處理

1. 缺失數據的表現
對於一些數據,可能某些值是空的,是缺失的。pandas中能夠有多種處理缺失數據的方式。在pandas中,缺失數據的表現是NaN(Not a Number),可使用isnull()函數檢測出是否有數據缺失。算法

In [4]: data = pd.Series(['aaa','bbb',np.nan,'ddd'])

In [5]: data
Out[5]:
0    aaa
1    bbb
2    NaN
3    ddd
dtype: object

In [6]: data.isnull()
Out[6]:
0    False
1    False
2     True
3    False
dtype: bool

isnull返回一個布爾型的對象,這些布爾值表示哪些值是缺失值NaN,該對象返回的類型和原類型同樣。數組

處理缺失數據的方式有多種,常見爲刪除缺失數據與填充缺失數據。函數

2. 丟棄缺失數據
pandas的dropna方法能夠有效的刪除掉缺失數據,對於Series來講,dropna方法返回一個僅含非空數據和索引值的Series:大數據

In [7]: data
Out[7]:
0    aaa
1    bbb
2    NaN
3    ddd
dtype: object

In [8]: data.dropna()
Out[8]:
0    aaa
1    bbb
3    ddd
dtype: object

對於DataFrame,dropna能夠刪除全部含有空值的行或列,也能夠根據我的刪除指定的行或列,dropna默認會刪除全部含有NaN的行:code

In [17]: df
Out[17]:
  name  age area
0   aa   18   北京
1  NaN   18   廣州
2   cc   20  NaN

In [18]: df.dropna()
Out[18]:
  name  age area
0   aa   18   北京

傳入how='all',那麼dropna只會刪除一行全是缺失值的行:對象

In [19]: df.loc[3]=[np.nan,np.nan,np.nan]

In [20]: df
Out[20]:
  name   age area
0   aa  18.0   北京
1  NaN  18.0   廣州
2   cc  20.0  NaN
3  NaN   NaN  NaN

In [21]: df.dropna(how='all')
Out[21]:
  name   age area
0   aa  18.0   北京
1  NaN  18.0   廣州
2   cc  20.0  NaN

若是要刪除有缺失值的一列,只須要傳入axis=1:索引

In [25]: df['avg'] = [20,30,40,50]

In [26]: df
Out[26]:
  name   age area  avg
0   aa  18.0   北京   20
1  NaN  18.0   廣州   30
2   cc  20.0  NaN   40
3  NaN   NaN  NaN   50

In [27]: df.dropna(axis=1)
Out[27]:
   avg
0   20
1   30
2   40
3   50

一樣,dropna(axis=1,how='all') 只會刪除整列都是缺失值的那一列。
若是想留下部分含有缺失值的數據做爲觀察,或者說只想刪除部分數據,那麼就須要使用thresh參數了,保留至少有n個非NaN數據的行/列:開發

In [52]: df
Out[52]:
  name   age area  avg
0   aa  18.0   北京   20 # 這一行4個值都不是NaN值,非NaN值爲4
1  NaN  18.0   廣州   30 # 有1個NaN值,非NaN值爲3
2   cc  20.0  NaN   40 # 有1個NaN值,非NaN值爲3
3  NaN   NaN  NaN   50 # 有3個NaN值,非NaN值爲1

In [53]: df.dropna(thresh=4) # 選取非空值至少有4個的行
Out[53]:
  name   age area  avg
0   aa  18.0   北京   20

In [54]: df.dropna(thresh=2) 
Out[54]:
  name   age area  avg
0   aa  18.0   北京   20
1  NaN  18.0   廣州   30
2   cc  20.0  NaN   40

In [55]: df.dropna(thresh=4,axis=1) # 選取非空值至少有4個的列
Out[55]:
   avg
0   20
1   30
2   40
3   50

3. 填充缺失數據
對於缺失數據不想丟棄而想填充新的數據,fillna()方法也許是首要選擇。經過一個常數調用fillna就會將缺失值替換爲那個常數值:字符串

In [62]: df
Out[62]:
  name   age area  avg
0   aa  18.0   北京   20
1  NaN  18.0   廣州   30
2   cc  20.0  NaN   40
3  NaN   NaN  NaN   50

In [64]: df.fillna(0)
Out[64]:
  name   age area  avg
0   aa  18.0   北京   20
1    0  18.0   廣州   30
2   cc  20.0    0   40
3    0   0.0    0   50

如果經過一個字典調用fillna,就能夠實現對不一樣的列填充不一樣的值:數據分析

In [61]: df.fillna({'name':'dd','age':22,'area':'深圳'})
Out[61]:
  name   age area  avg
0   aa  18.0   北京   20
1   dd  18.0   廣州   30
2   cc  20.0   深圳   40
3   dd  22.0   深圳   50

fillna默認會返回新對象,但也能夠對現有對象進行就地修改:

In [65]: df.fillna(0,inplace=True)

In [66]: df
Out[66]:
  name   age area  avg
0   aa  18.0   北京   20
1    0  18.0   廣州   30
2   cc  20.0    0   40
3    0   0.0    0   50

數據去重

數據中也有可能出現多行數據重複的狀況,DataFrame的duplicated方法返回一個布爾型的對象,表示各行是不是重複的行,它每次都會對比前面出現的行,若是出現與前面出現的行同樣的行,那麼這一行就是重複行:

In [68]: data
Out[68]:
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4
6  two   4 # 這一行與前一行重複,因爲這一行在第5行後,因此會被判斷爲重複行

In [69]: data.duplicated()
Out[69]:
0    False
1    False
2    False
3    False
4    False
5    False 
6     True 
dtype: bool

drop_duplicates方法,它會返回一個DataFrame,重複的數組會標爲False而且刪除:

In [70]: data.drop_duplicates()
Out[70]:
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4

上面兩個方法默認會判斷所有列,若是隻想根據一列進行重複值判斷,能夠傳入包含列索引的列表:

In [75]: data
Out[75]:
    k1  k2  v1
0  one   1   0
1  two   1   1
2  one   2   2
3  two   3   3
4  one   3   4
5  two   4   5
6  two   4   6

In [76]: data.drop_duplicates(['k1'])
Out[76]:
    k1  k2  v1
0  one   1   0
1  two   1   1

duplicated和drop_duplicates默認保留的是第一個出現的值組合。傳入keep='last'則保留最後一個:

In [51]: data.drop_duplicates(['k1', 'k2'], keep='last')
Out[51]: 
    k1  k2  v1
0  one   1   0
1  two   1   1
2  one   2   2
3  two   3   3
4  one   3   4
6  two   4   6

數據替換

有的時候需求是將數據框的某個值替換掉,pandas提供了replace方法,注意它與字符串的replace方法不同。
pandas的replace方法操做的對象是DataFrame的值。

In [83]: data
Out[83]:
   age name
0  -20   小明
1   20   老王
2   23   蘋果

In [84]: data.replace(-20,0) # 將-20替換爲0
Out[84]:
   age name
0    0   小明
1   20   老王
2   23   蘋果

若是要讓替換值有不一樣的值,要傳入一個列表

In [88]: data.replace(['小明','老王'],['獼猴桃','西瓜'])
Out[88]:
    age name
0  -20  獼猴桃
1   20   西瓜
2   23   蘋果

替換多個值:

In [90]: data.replace(['小明','老王'],'蘋果')
Out[90]:
   age name
0  -20   蘋果
1   20   蘋果
2   23   蘋果

數據文本函數

假若有以下數據:

In [94]: data
Out[94]:
     position   avg              brief
0    Java開發    10     ['開發','工程師','高新']
1    數據分析師   13      ['分析師','大數據']
2    算法工程師   15        ['算法','數學']

需求是在avg的列的值加上字母k,去掉brief列的值的方括號和單引號。pandas中有不少種方法能夠實現,下面介紹一種簡單的方法。

+k需求:

In [98]: data.avg
Out[98]:
0    10
1    13
2    15
Name: avg, dtype: int64

In [99]: data.avg.astype('str')+'k'
Out[99]:
0    10k
1    13k
2    15k
Name: avg, dtype: object

In [100]: data['avg'] =  data.avg.astype('str')+'k'

In [101]: data
Out[101]:
  position  avg              brief
0   Java開發  10k  ['開發','工程師','高新']
1    數據分析師  13k      ['分析師','大數據']
2    算法工程師  15k        ['算法','數學']

去除方括號和去除單引號需求

In [104]: data.brief
Out[104]:
0    ['開發','工程師','高新']
1        ['分析師','大數據']
2          ['算法','數學']
Name: brief, dtype: object

In [105]: data.brief.str[1:-1]
Out[105]:
0    '開發','工程師','高新'
1        '分析師','大數據'
2          '算法','數學'
Name: brief, dtype: object

In [106]: data.brief.str[1:-1].str.replace("'","")
Out[106]:
0    開發,工程師,高新
1      分析師,大數據
2        算法,數學
Name: brief, dtype: object
相關文章
相關標籤/搜索