如何替換dataframe中的nan?

在做數據清洗等工作時,必不可少的環節就是缺失值處理。在採用pandas讀取或處理數據時,dataframe的缺失值默認是用nan填充的。但大多數情況下,我們需要的是None或者Null值而不是nan.所以,如何替換dataframe中的nan呢?

替換nan的方法有很多,本文總結了三個方法。dataframe.fillna()方法,dataframe.applymap()以及dataframe.where()方法。本文通過測試數據對每個方法進行分析。最終選擇使用哪個方法可結合本文的分析,根據真實場景進行取捨。

1.準備測試數據

types = {'name': str, 'cost': float, 'age': float, 'phone': str}
# 注意age不能指定爲int類型,
# 指定類型讀取數據
data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0, dtype=types)
#查看數據
print(data)
# 查看每列的數據類型
print(data.dtypes)

注意:age列中含有缺失值,所以不能指定爲int型,否則會報錯ValueError: Unable to convert column age to type <class 'int'>

輸出結果:

  name          cost   age        phone
0   小青           NaN  25.0  12341234123
1   小紅  1.628771e+06  23.0  12341234124
2   小明  8.438553e+05  26.0  12341234125
3   小李  1.699444e+06  25.0  12341234126
4   小王  2.635745e+06   NaN  12341234127
5   小張  1.168142e+06  25.0          nan
6   小劉  1.607670e+06  28.0  12341234129
7  nan  1.234523e+04  27.0          nan
name      object
cost     float64
age      float64
phone     object
dtype: object

Process finished with exit code 0

2.dataframe.fillna();該方法使用指定的方法填充NA / NaN值

values = {'name': '', 'cost': 0, 'age': -1, 'phone': ''}
data.fillna(value=values,inplace=True)
print(data)

輸出結果:

  name          cost   age        phone
0   小青  0.000000e+00  25.0  12341234123
1   小紅  1.628771e+06  23.0  12341234124
2   小明  8.438553e+05  26.0  12341234125
3   小李  1.699444e+06  25.0  12341234126
4   小王  2.635745e+06  -1.0  12341234127
5   小張  1.168142e+06  25.0          nan
6   小劉  1.607670e+06  28.0  12341234129
7  nan  1.234523e+04  27.0          nan

Process finished with exit code 0

從上面的輸出結果可以看出:fillna()方法必須要指定一個填充且不爲None的值,且object類型的填充並未生效

3.dataframe.applymap()自定義處理方法

data = data.applymap(lambda x: x if str(x) != 'nan' else None)
# 查看數據
print(data)

輸出結果:

   name          cost   age        phone
0    小青           NaN  25.0  12341234123
1    小紅  1.628771e+06  23.0  12341234124
2    小明  8.438553e+05  26.0  12341234125
3    小李  1.699444e+06  25.0  12341234126
4    小王  2.635745e+06   NaN  12341234127
5    小張  1.168142e+06  25.0         None
6    小劉  1.607670e+06  28.0  12341234129
7  None  1.234523e+04  27.0         None

Process finished with exit code 0

由上面的輸出結果可以看出:該方法只對字符串類型的數據生效,數值類型的數據又不能起作用了

4.dataframe.where()篩選需要的數據,如果符合要求就返回原始值,如果不符合要求就用參數other的值填充,other的默認值爲numpy.nan

4.1不指定數據類型

 

data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0)
data = data.where((data.notna()),None)
# 查看數據
print(data)

輸出結果:

   name         cost   age        phone
0    小青         None    25  1.23412e+10
1    小紅  1.62877e+06    23  1.23412e+10
2    小明       843855    26  1.23412e+10
3    小李  1.69944e+06    25  1.23412e+10
4    小王  2.63574e+06  None  1.23412e+10
5    小張  1.16814e+06    25         None
6    小劉  1.60767e+06    28  1.23412e+10
7  None      12345.2    27         None

Process finished with exit code 0

注意:上面代碼中使用where方法時,讀取測試數據並沒有指定name爲str類型,如果指定爲str類型,則pandas讀取該列時缺失值採用字符串'nan'進行填充,data.notna()返回的是True,如果不指定name列的類型,則該列的缺失值使用float類型的numpy.nan填充,data.notna()返回的是False。

4.2 指定數據類型,可自定的where方法的cond參數

types = {'name': str, 'cost': float, 'age': float, 'phone': str}
# 指定類型讀取數據
data = pd.read_excel('../../test.xlsx', sheet_name='Sheet1', header=0, dtype=types)
data = data.where((data.applymap(lambda x: True if str(x) != 'nan' else False)), None)
# 查看數據
print(data)

輸出結果:

   name         cost   age        phone
0    小青         None    25  12341234123
1    小紅  1.62877e+06    23  12341234124
2    小明       843855    26  12341234125
3    小李  1.69944e+06    25  12341234126
4    小王  2.63574e+06  None  12341234127
5    小張  1.16814e+06    25         None
6    小劉  1.60767e+06    28  12341234129
7  None      12345.2    27         None

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章