Dataframeのnanをどのように置き換えますか?


データ洗浄などの作業を行う際に欠かせないのが欠落値処理です.pandasを使用してデータを読み取りまたは処理する場合、dataframeの欠落値はデフォルトでnanで埋め込まれます.しかし、多くの場合、nanではなくNoneまたはNull値が必要です.では、dataframeのnanをどのように置き換えますか?
nanを置き換える方法はいろいろありますが,本稿では3つの方法をまとめました.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とエラーが発生します.
出力結果:
  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メソッドを使用する場合、読み出しテストデータにはstrタイプとしてnameが指定されていません.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