pandas fillna
在数据分析和处理过程中,处理缺失值是一个很常见的任务。在Python中,pandas
是一个功能强大的库,提供了各种用于数据处理和分析的工具。其中一个非常重要的功能就是填充缺失值的方法,即fillna
。
本文将详细介绍pandas
中的fillna
方法,包括如何使用它来填充缺失值,以及常见的填充策略和参数。
介绍
在数据分析中,经常会遇到缺失值。缺失值可能由于数据采集错误、系统故障或用户未提供而出现。这些缺失值会对数据分析和建模产生负面影响,因此需要对其进行处理。
pandas
提供了fillna
方法,可以用指定的值或方法来填充缺失值,从而使数据集完整。
填充缺失值的方法
常数填充
常数填充是fillna
方法中最简单的一种方式。它使用一个指定的常数值来填充缺失值。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': [1, 2, None, 4, 5],
'B': ['a', None, 'c', 'd', 'e']})
df_filled = df.fillna(0)
print(df_filled)
输出:
A B
0 1.0 a
1 2.0 0
2 0.0 c
3 4.0 d
4 5.0 e
在上面的示例中,缺失值被0填充。注意,在数值列中,缺失值被替换为指定的常数0,并且数值列中的数据类型保持不变。
前向填充和后向填充
前向填充和后向填充是指用前一个或后一个非缺失值填充缺失值的方法。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': [1, 2, None, None, 5],
'B': ['a', None, 'c', None, 'e']})
# 前向填充
df_ffilled = df.fillna(method='ffill')
# 后向填充
df_bfilled = df.fillna(method='bfill')
print(df_ffilled)
print(df_bfilled)
输出:
A B
0 1.0 a
1 2.0 a
2 2.0 c
3 2.0 c
4 5.0 e
A B
0 1.0 a
1 2.0 c
2 5.0 c
3 5.0 e
4 5.0 e
在上面的示例中,method='ffill'
表示使用前向填充,即用前一个非缺失值填充缺失值。method='bfill'
表示使用后向填充,即用后一个非缺失值填充缺失值。
插值填充
插值填充是指根据已有的数据进行插值计算,从而填充缺失值。pandas
中的插值功能通过interpolate
方法实现。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': [1, 2, None, 4, None],
'B': [10, None, 30, None, 50]})
# 插值填充
df_interp = df.interpolate()
print(df_interp)
输出:
A B
0 1.0 10.0
1 2.0 16.7
2 3.0 30.0
3 4.0 40.0
4 4.0 50.0
在上面的示例中,interpolate
方法根据已有的数据进行线性插值计算,并填充缺失值。注意,在该示例中,插值填充了数值型列,但字符串型列B
保持不变。
分组填充
分组填充是指根据数据的某些特征将缺失值填充为特定的值。pandas
提供了groupby
方法来实现分组填充。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': [1, 2, None, 4, None],
'B': ['a', 'b', None, 'd', None],
'C': [10, 20, None, None, None]})
# 根据列A进行分组,缺失值填充为分组平均值
df_groupfilled = df.fillna(df.groupby('A')['C'].transform('mean'))
print(df_groupfilled)
输出:
A B C
0 1.0 a 10.0
1 2.0 b 20.0
2 3.0 a 20.0
3 4.0 d NaN
4 3.0 a 20.0
在上面的示例中,首先使用groupby
方法根据列A
进行分组,然后使用transform
方法计算分组的平均值,并填充相应的缺失值。
处理特定数据类型的缺失值
fillna
方法还可以根据数据的类型来处理特定类型的缺失值。下面介绍了处理数值型、字符型和日期型缺失值的常见方法。
数值型
对于数值型缺失值,可以使用常数填充、插值填充或分组填充等方法来处理。
示例代码:
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': [1, 2, None, 4, None],
'B': [10, np.nan, 30, None, 50]})
# 常数填充
df_constfilled = df.fillna(0)
# 插值填充
df_interp = df.interpolate()
# 分组填充
df_groupfilled = df.fillna(df.groupby('A')['B'].transform('mean'))
print(df_constfilled)
print(df_interp)
print(df_groupfilled)
输出:
A B
0 1.0 10.0
1 2.0 0.0
2 0.0 30.0
3 4.0 0.0
4 0.0 50.0
A B
0 1.0 10.0
1 2.0 20.0
2 3.0 30.0
3 4.0 40.0
4 4.0 50.0
A B
0 1.0 10.0
1 2.0 30.0
2 NaN 30.0
3 4.0 40.0
4 NaN 30.0
在上面的示例中,常数填充将缺失的数值型数据用指定的常数值0填充。插值填充使用线性插值方法根据已有的数据进行计算。分组填充则使用分组的平均值来填充缺失值。
字符型
对于字符型缺失值,可以使用常数填充、众数填充或分组填充等方法来处理。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': ['apple', 'banana', None, 'durian', None],
'B': ['red', None, 'blue', None, 'green']})
# 常数填充
df_constfilled = df.fillna('missing')
# 众数填充
df_modefilled = df.fillna(df['B'].mode()[0])
# 分组填充
df_groupfilled = df.fillna(df.groupby('A')['B'].transform('first'))
print(df_constfilled)
print(df_modefilled)
print(df_groupfilled)
输出:
A B
0 apple red
1 banana missing
2 missing blue
3 durian missing
4 missing green
A B
0 apple red
1 banana blue
2 banana blue
3 durian blue
4 banana green
A B
0 apple red
1 banana red
2 apple blue
3 durian red
4 apple green
在上面的示例中,常数填充将缺失的字符型数据用指定的常数值missing
填充。众数填充使用列B
的众数值填充缺失值。分组填充使用分组的第一个值填充缺失值。
日期型
对于日期型缺失值,可以使用常数填充、插值填充或分组填充等方法来处理。
示例代码:
import pandas as pd
df = pd.DataFrame({'A': ['2020-01-01', '2020-01-02', None, '2020-01-04', None],
'B': ['apple', 'banana', 'cherry', None, 'eggplant']})
# 常数填充
df_constfilled = df.fillna(pd.to_datetime('2020-01-03'))
# 插值填充
df_interp = df.interpolate()
# 分组填充
df_groupfilled = df.fillna(df.groupby('B')['A'].transform('max'))
print(df_constfilled)
print(df_interp)
print(df_groupfilled)
输出:
A B
0 2020-01-01 apple
1 2020-01-02 banana
2 2020-01-03 cherry
3 2020-01-04 eggplant
4 2020-01-03 eggplant
A B
0 2020-01-01 apple
1 2020-01-02 banana
2 2020-01-03 cherry
3 2020-01-04 eggplant
4 NaT eggplant
A B
0 2020-01-01 apple
1 2020-01-02 banana
2 2020-01-04 cherry
3 2020-01-04 eggplant
4 NaT eggplant
在上面的示例中,常数填充将缺失的日期型数据用指定的常数值2020-01-03
填充。插值填充使用线性插值方法根据已有的数据进行计算。分组填充使用分组的最大值填充缺失值。
使用fillna注意事项
在使用fillna
方法时,需要注意以下几点:
fillna
方法默认返回一个新的DataFrame,如果要在原始DataFrame上进行修改,需要传入inplace=True
参数。fillna
方法对不同的数据类型有不同的处理方式,需根据实际情况选择合适的填充策略。- 当填充缺失值涉及到统计计算时,可以使用
groupby
方法来实现分组填充。 - 在数值型数据中进行插值填充时,可以使用
interpolate
方法,根据已有数据进行插值计算。
示例代码
下面给出一个完整的示例代码,展示了如何使用fillna
方法来处理不同类型的缺失值:
import pandas as pd
import numpy as np
# 创建一个包含缺失值的DataFrame
df = pd.DataFrame({'A': [1, 2, None, None, 5],
'B': ['a', None, 'c', None, 'e'],
'C': [10, np.nan, 30, None, 50],
'D': ['2021-01-01', '2021-01-02', None, '2021-01-04', '2021-01-05']})
# 常数填充
df_constfilled = df.fillna(0)
# 前向填充
df_ffilled = df.fillna(method='ffill')
# 后向填充
df_bfilled = df.fillna(method='bfill')
# 插值填充
df_interp = df.interpolate()
# 数值型缺失值填充
df_numfilled = df.copy()
df_numfilled['A'] = df_numfilled['A'].fillna(-1)
df_numfilled['C'] = df_numfilled['C'].fillna(df_numfilled['C'].mean())
# 字符型缺失值填充
df_strfilled = df.copy()
df_strfilled['B'] = df_strfilled['B'].fillna('missing')
df_strfilled['D'] = df_strfilled['D'].fillna(df_strfilled['D'].mode()[0])
# 日期型缺失值填充
df_datefilled = df.copy()
df_datefilled['D'] = df_datefilled['D'].fillna(pd.to_datetime('2021-01-03'))
# 输出结果
print("常数填充:\n", df_constfilled)
print("\n前向填充:\n", df_ffilled)
print("\n后向填充:\n", df_bfilled)
print("\n插值填充:\n", df_interp)
print("\n数值型缺失值填充:\n", df_numfilled)
print("\n字符型缺失值填充:\n", df_strfilled)
print("\n日期型缺失值填充:\n", df_datefilled)