Python Pandas处理缺失值NaN:检测、删除与填充详解

白榆
白榆
发布时间:2026-10-12 | 4人浏览过
原创

本文详解Python Pandas中缺失值NaN的处理方法。涵盖使用isnull()检测空值,通过dropna()按条件删除含缺失值的行或列,以及利用fillna()进行统一值、字典映射、统计量或前后向填充。包含具体代码示例与参数说明,帮助高效清洗数据。

前言

在使用Pandas读取CSV文件时,若遇到空元素,系统会将其识别为缺失值NaN(Not a Number,即非数字)。

处理缺失值主要涉及两种操作:使用dropna()方法移除包含缺失值的记录,或使用fillna()方法用指定值进行填充替换。

若需提取包含缺失值的行或列,可利用isnull()方法判断元素是否为空。

1. 检查缺失值NaN

例如,读取并处理包含空值的CSV文件。

import pandas as pd
import numpy as np
import math

df = pd.read_csv('./data/05/sample_pandas_normal_nan.csv')
print(df)
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 1      NaN   NaN   NaN    NaN    NaN
# 2  Charlie   NaN    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen   NaN    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

使用pandas.isnull()检查所有缺失值:

print(df.isnull())
# 或者 
print(pd.isnull(df))
#     name    age  state  point  other
# 0  False  False  False   True   True
# 1   True   True   True   True   True
# 2  False   True  False   True   True
# 3  False  False  False  False   True
# 4  False   True  False  False   True
# 5  False  False   True   True   True

检查‘name’列中的缺失值:

print(df['name'].isnull())
# 0    False
# 1     True
# 2    False
# 3    False
# 4    False
# 5    False
Name: name, dtype: bool

也可使用numpy.isnan()和math.isnan(),但需分别导入NumPy和math库:

print(pd.isnull(df.at[0, 'point']))
print(np.isnan(df.at[0, 'point']))
print(math.isnan(df.at[0, 'point']))
# True
# True
# True

2. Pandas中NaN的类型

在Pandas中,None、np.nan、math.nan和pd.np.nan均被视为缺失值NaN。

s_nan = pd.Series([None, np.nan, math.nan, pd.np.nan])
print(s_nan)
# 0   NaN
# 1   NaN
# 2   NaN
# 3   NaN
# dtype: float64

print(s_nan[0])
print(type(s_nan[0]))
# nan
# <class 'numpy.float64'>

print(s_nan.isnull())
# 0    True
# 1    True
# 2    True
# 3    True
# dtype: bool

3. NaN的删除 dropna()

使用dropna()方法可删除缺失值。

默认情况下,该方法返回新对象而不修改原始数据;若设置参数inplace=True,则直接修改原始对象。

print(df)
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 1      NaN   NaN   NaN    NaN    NaN
# 2  Charlie   NaN    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen   NaN    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

3.1 删除所有值均缺失的行/列

若指定参数how='all',则仅删除所有值均为缺失值的行。

print(df.dropna(how='all'))
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 2  Charlie   NaN    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen   NaN    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

若设置axis=1,则删除所有值均为缺失值的列。

print(df.dropna(how='all', axis=1))
#       name   age state  point
# 0    Alice  24.0    NY    NaN
# 1      NaN   NaN   NaN    NaN
# 2  Charlie   NaN    CA    NaN
# 3     Dave  68.0    TX   70.0
# 4    Ellen   NaN    CA   88.0
# 5    Frank  30.0   NaN    NaN

删除所有值均缺失的行和列的数据:

df2 = df.dropna(how='all').dropna(how='all', axis=1)
print(df2)
#       name   age state  point
# 0    Alice  24.0    NY    NaN
# 2  Charlie   NaN    CA    NaN
# 3     Dave  68.0    TX   70.0
# 4    Ellen   NaN    CA   88.0
# 5    Frank  30.0   NaN    NaN

3.2 删除至少包含一个缺失值的行/列

基于上述删除所有缺失值后的数据df2:

print(df2)
#       name   age state  point
# 0    Alice  24.0    NY    NaN
# 2  Charlie   NaN    CA    NaN
# 3     Dave  68.0    TX   70.0
# 4    Ellen   NaN    CA   88.0
# 5    Frank  30.0   NaN    NaN

若指定参数how='any',则删除至少包含一个缺失值的行。默认情况下how='any'。

print(df2.dropna(how='any'))
#    name   age state  point
# 3  Dave  68.0    TX   70.0

print(df2.dropna())
#    name   age state  point
# 3  Dave  68.0    TX   70.0

若设置axis=1,则删除包含至少一个缺失值的列。

print(df2.dropna(how='any', axis=1))
#       name
# 0    Alice
# 2  Charlie
# 3     Dave
# 4    Ellen
# 5    Frank

3.3 根据不缺少值的元素数量删除行/列

通过在参数thresh中指定数字,可根据非缺失值的数量来删除行和列。

例如,若thresh=3,则保留包含三个或更多非缺失值的行,并删除其他行(即包含两个或更少非缺失值的行)。

print(df.dropna(thresh=3))
#     name   age state  point  other
# 0  Alice  24.0    NY    NaN    NaN
# 3   Dave  68.0    TX   70.0    NaN
# 4  Ellen   NaN    CA   88.0    NaN

若axis=1,则此规则应用于列。

print(df.dropna(thresh=3, axis=1))
#       name   age state
# 0    Alice  24.0    NY
# 1      NaN   NaN   NaN
# 2  Charlie   NaN    CA
# 3     Dave  68.0    TX
# 4    Ellen   NaN    CA
# 5    Frank  30.0   NaN

3.4 删除特定行/列中缺少值的列/行

若需基于特定行或列进行删除,请在参数subset中指定目标行或列的标签列表。由于必须是列表,至少需指定一个目标,例如subset=['name']。默认情况下,将删除指定列中缺失值的行。

print(df.dropna(subset=['age']))
#     name   age state  point  other
# 0  Alice  24.0    NY    NaN    NaN
# 3   Dave  68.0    TX   70.0    NaN
# 5  Frank  30.0   NaN    NaN    NaN

若指定多列,则默认删除所有指定列中均缺失值的行。

print(df.dropna(subset=['age', 'state']))
#     name   age state  point  other
# 0  Alice  24.0    NY    NaN    NaN
# 3   Dave  68.0    TX   70.0    NaN

若参数how='all',则仅删除所有指定列均缺失值的行。

print(df.dropna(subset=['age', 'state'], how='all'))
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 2  Charlie   NaN    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen   NaN    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

4. 缺失值NaN的替换(填充) fillna()

可以使用fillna()方法将缺失值替换为任意指定值。

默认情况下,该方法返回新对象而不修改原始数据;若设置参数inplace=True,则直接修改原始对象。

print(df)
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 1      NaN   NaN   NaN    NaN    NaN
# 2  Charlie   NaN    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen   NaN    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

4.1 用通用值统一替换

若指定要替换的值,则所有缺失值NaN都将替换为该值。

print(df.fillna(0))
#       name   age state  point  other
# 0    Alice  24.0    NY    0.0    0.0
# 1        0   0.0     0    0.0    0.0
# 2  Charlie   0.0    CA    0.0    0.0
# 3     Dave  68.0    TX   70.0    0.0
# 4    Ellen   0.0    CA   88.0    0.0
# 5    Frank  30.0     0    0.0    0.0

4.2 为每列替换不同的值

当参数指定为字典时,每列将替换为不同的值。字典键为列标签(列名),值为要替换的值。未指定的列仍保持缺失值NaN。

print(df.fillna({'name': 'XXX', 'age': 20, 'point': 0}))
#       name   age state  point  other
# 0    Alice  24.0    NY    0.0    NaN
# 1      XXX  20.0   NaN    0.0    NaN
# 2  Charlie  20.0    CA    0.0    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen  20.0    CA   88.0    NaN
# 5    Frank  30.0   NaN    0.0    NaN

除字典外,还可指定pandas.Series。若列标签与pandas.Series中的索引标签匹配,则缺失值将替换为Series中的对应值。未匹配的列仍保持缺失值。

s_for_fill = pd.Series(['ZZZ', 100], index=['name', 'age'])
print(s_for_fill)
# name    ZZZ
# age     100
# dtype: object

print(df.fillna(s_for_fill))
#       name    age state  point  other
# 0    Alice   24.0    NY    NaN    NaN
# 1      ZZZ  100.0   NaN    NaN    NaN
# 2  Charlie  100.0    CA    NaN    NaN
# 3     Dave   68.0    TX   70.0    NaN
# 4    Ellen  100.0    CA   88.0    NaN
# 5    Frank   30.0   NaN    NaN    NaN

4.3 用每列的平均值,中位数,众数等替换

可使用mean()方法计算每列的平均值,结果为pandas.Series。计算时会自动排除缺失值。

print(df.mean())
# age      40.666667
# point    79.000000
# other          NaN
# dtype: float64

若将此pandas.Series作为fillna()的参数,则相应列中的缺失值将替换为平均值。

print(df.fillna(df.mean()))
#       name        age state  point  other
# 0    Alice  24.000000    NY   79.0    NaN
# 1      NaN  40.666667   NaN   79.0    NaN
# 2  Charlie  40.666667    CA   79.0    NaN
# 3     Dave  68.000000    TX   70.0    NaN
# 4    Ellen  40.666667    CA   88.0    NaN
# 5    Frank  30.000000   NaN   79.0    NaN

同样,若需替换为中位数,请使用median()方法。对于偶数个数据,中位数为中间两个值的平均数。

print(df.fillna(df.median()))
#       name   age state  point  other
# 0    Alice  24.0    NY   79.0    NaN
# 1      NaN  30.0   NaN   79.0    NaN
# 2  Charlie  30.0    CA   79.0    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen  30.0    CA   88.0    NaN
# 5    Frank  30.0   NaN   79.0    NaN

4.4 替换为上一个或下一个值

通过method参数,可替换为前一个或后一个值,而非指定值。若method='ffill',则用前一个值替换;若method='bfill',则用后一个值替换。此方法适用于时间序列数据。

print(df.fillna(method='ffill'))
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 1    Alice  24.0    NY    NaN    NaN
# 2  Charlie  24.0    CA    NaN    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen  68.0    CA   88.0    NaN
# 5    Frank  30.0    CA   88.0    NaN

print(df.fillna(method='bfill'))
#       name   age state  point  other
# 0    Alice  24.0    NY   70.0    NaN
# 1  Charlie  68.0    CA   70.0    NaN
# 2  Charlie  68.0    CA   70.0    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen  30.0    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

使用参数limit,可指定连续替换的最大数量。

print(df.fillna(method='bfill', limit=1))
#       name   age state  point  other
# 0    Alice  24.0    NY    NaN    NaN
# 1  Charlie   NaN    CA    NaN    NaN
# 2  Charlie  68.0    CA   70.0    NaN
# 3     Dave  68.0    TX   70.0    NaN
# 4    Ellen  30.0    CA   88.0    NaN
# 5    Frank  30.0   NaN    NaN    NaN

参考博客:

Pandas删除,替换并提取其中的缺失值NaN(dropna,fillna,isnull): https://www.jb51.net/article/233846.htm

总结

到此这篇关于Python Pandas中缺失值NaN的判断,删除及替换的文章就介绍到这了,更多相关Pandas缺失值NaN判断删除及替换内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表