1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 05_Pandas删除 替换并提取其中的缺失值NaN(dropna fillna isnull)

05_Pandas删除 替换并提取其中的缺失值NaN(dropna fillna isnull)

时间:2023-12-17 10:19:51

相关推荐

05_Pandas删除 替换并提取其中的缺失值NaN(dropna fillna isnull)

05_Pandas删除,替换并提取其中的缺失值NaN(dropna,fillna,isnull)

例如,当使用pandas读取csv文件时,如果元素为空,则将其视为缺失值NaN(非数字)。

使用dropna()方法删除缺失值,使用fillna()方法用其他值替换(填充)缺失值。

如果要提取包含缺失值的行或列,使用isnull()方法确定元素是否缺失。

例如,读取并使用包含带read_csv的空格的csv文件。

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

在此,将对以下内容进行说明。

Pandas中缺失值NaN的介绍将缺失值作为Pandas中的缺失值NaN缺失值NaN的删除方法 删除所有值均缺失的行/列删除至少包含一个缺失值的行/列根据不缺失值的元素数量删除行/列删除特定行/列中缺失值的列/行pandas.Series 替换(填充)缺失值 用通用值统一替换为每列替换不同的值用每列的平均值,中位数,最频繁值等替换替换为上一个或下一个值指定连续更换的最大数量pandas.Series 提取缺失值 提取特定行/列中缺少值的列/行提取至少包含一个缺失值的行/列

Pandas中缺少值NaN的介绍

在Pandas中,如果列包含任何缺失值NaN,则即使所有其他值均为整数int,该列的dtype也将被视为浮点。

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# 1NaN NaN NaN NaN NaN# 2 Charlie NaN CA NaN NaN# 3Dave 68.0 TX 70.0 NaN# 4 Ellen NaN CA 88.0 NaN# 5 Frank 30.0 NaN NaN NaNprint(df.dtypes)# nameobject# agefloat64# stateobject# point float64# other float64# dtype: object

虽然编写代码时不必担心,但是对象类型列的缺失值是内置的float,而浮点类型列的缺失值是NumPy的numpy.float64。数字可能会因环境而异)。

print(df.at[1, 'name'])print(type(df.at[1, 'name']))# nan# <class 'float'>print(df.at[0, 'point'])print(type(df.at[0, 'point']))# nan# <class 'numpy.float64'>

使用pandas.isnull()检查缺失的值。也可以使用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

注意,用==与np.nan或math.nan比较会返回False。

print(df.at[0, 'point'] == np.nan)# False

将缺失值作为Pandas中的缺少值NaN

在Pandas中,将None,np.nan,math.nan和pd.np.nan视为缺失值NaN,以下所述的dropna()和fillna()。另外,只要导入了Pandas,pd.np.nan就可以不导入NumPy了。 在numpy.float64中,None也转换为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: float64print(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

如上所述,如果包含缺失值,则将整数int类型值强制转换为浮点浮点类型。

s_nan_int = pd.Series([None, pd.np.nan, 0, 1])print(s_nan_int)# 0 NaN# 1 NaN# 2 0.0# 3 1.0# dtype: float64print(s_nan_int.isnull())# 0True# 1True# 2 False# 3 False# dtype: bool

如果包含字符串str值,则其pandas.Series(和pandas.DataFrame列)数据类型将为object。 None不会转换为numpy.float64的nan并保持为None,但是它是dropna()和fillna()的对象,因此在实践中无需担心。

s_nan_str = pd.Series([None, pd.np.nan, 'NaN', 'nan'])print(s_nan_str)# 0 None# 1NaN# 2NaN# 3nan# dtype: objectprint(s_nan_str[0])print(type(s_nan_str[0]))# None# <class 'NoneType'>print(s_nan_str.isnull())# 0True# 1True# 2 False# 3 False# dtype: bool

如果有一个您想当作缺失值的值,例如字符串“ NaN”,则可以使用replace()方法将其替换为缺失值。

s_nan_str_replace = s_nan_str.replace({'NaN': pd.np.nan, 'nan': pd.np.nan})print(s_nan_str_replace)# 0 NaN# 1 NaN# 2 NaN# 3 NaN# dtype: float64print(s_nan_str_replace.isnull())# 0 True# 1 True# 2 True# 3 True# dtype: bool

请注意,在上面的示例中,在读取read_csv()之类的文件的函数中,空字符串(空白)和字符串’NaN’,'null’默认情况下视为缺失值。有关详细信息,请参见以下文章。

03_Pandas读取csv/tsv文件(read_csv,read_table)

缺少值NaN的删除方法

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

默认情况下,将返回新对象,并且不会更改原始对象,但是参数inplace = True会更改原始对象本身。 以较早加载的pandas.DataFrame为例。

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

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

如果指定了参数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# 3Dave 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# 1NaN NaN NaN NaN# 2 Charlie NaN CA NaN# 3Dave 68.0 TX 70.0# 4 Ellen NaN CA 88.0# 5 Frank 30.0 NaN NaN

如果axis = [0,1],则会删除所有缺失值的行和列,但是从版本0.23.0开始,将不推荐使用(不推荐使用)轴列表和元组规范。 如果要同时应用于行和列,则可以重复应用dropna()。

print(df.dropna(how='all').dropna(how='all', axis=1))# name age state point# 0 Alice 24.0 NY NaN# 2 Charlie NaN CA NaN# 3Dave 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# 3Dave 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.0print(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# 3Dave# 4 Ellen# 5 Frank

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

通过在参数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# 1NaN NaN NaN# 2 Charlie NaN CA# 3Dave 68.0 TX# 4 Ellen NaN CA# 5 Frank 30.0 NaN

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

如果要基于特定的行/列删除,请在列表的参数子集中指定要定位的行/列标签。由于它必须是列表,因此请至少指定一个目标,例如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# 3Dave 68.0 TX 70.0 NaN# 4 Ellen NaN CA 88.0 NaN# 5 Frank 30.0 NaN NaN NaN

如果axis = 1,则删除子集指定的行中缺少值的列。参数how也可以使用。

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

pandas.Series

如果数据是一维pandas.Series,则只需调用dropna()。缺少的值将被删除。

s = df['age']print(s)# 0 24.0# 1NaN# 2NaN# 3 68.0# 4NaN# 5 30.0# Name: age, dtype: float64print(s.dropna())# 0 24.0# 3 68.0# 5 30.0# Name: age, dtype: float64

替换(填充)缺失值

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

默认情况下,将返回新对象,并且不会更改原始对象,但是参数inplace = True会更改原始对象本身。 以较早加载的pandas.DataFrame为例。

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

用通用值统一替换

如果指定要用参数替换的值,则所有缺少的值NaN都将替换为该值。

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

为每列替换不同的值

将字典指定为参数时,每列将替换一个不同的值。字典键是列标签(列名),而值是要替换的值。未指定的列仍缺少值NaN。

print(df.fillna({'name': 'XXX', 'age': 20, 'point': 0}))# name age state point other# 0 Alice 24.0 NY 0.0 NaN# 1XXX 20.0 NaN 0.0 NaN# 2 Charlie 20.0 CA 0.0 NaN# 3Dave 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中的标签匹配的列标签(列名)的列中缺少的值将替换为pandas.Series值。与pandas.Series标签不对应的列仍然缺少值。

s_for_fill = pd.Series(['ZZZ', 100], index=['name', 'age'])print(s_for_fill)# name ZZZ# age100# dtype: objectprint(df.fillna(s_for_fill))# name age state point other# 0 Alice 24.0 NY NaN NaN# 1ZZZ 100.0 NaN NaN NaN# 2 Charlie 100.0 CA NaN NaN# 3Dave 68.0 TX 70.0 NaN# 4 Ellen 100.0 CA 88.0 NaN# 5 Frank 30.0 NaN NaN NaN

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

可以使用mean()方法计算每列的平均值。结果是pandas.Series。缺失值将被排除并计算。

print(df.mean())# age40.666667# point 79.000000# otherNaN# dtype: float64

如果将此pandas.Series指定为fillna()的参数,则如上所述,将相应列中的缺失值替换为平均值。

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

同样,如果要替换中位数,请使用中位数()方法。在偶数的情况下,两个中心值的平均值是中值。

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

最频繁值的取得。mode()返回pandas.DataFrame,因此iloc [0]将第一行作为pandas.Series。

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

尽管在此示例中这不是问题,但是诸如mean()之类的方法可能会返回意外的值,因为默认情况下它们不仅尝试处理数字列,而且还尝试处理其他类型的列。 如果参数numeric_only = True,则目标仅限于数字列。同样在这种情况下,布尔类型列也被处理为True = 1,False = 0。

替换为上一个或下一个值

通过使用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# 3Dave 68.0 TX 70.0 NaN# 4 Ellen 68.0 CA 88.0 NaN# 5 Frank 30.0 CA 88.0 NaNprint(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# 3Dave 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# 3Dave 68.0 TX 70.0 NaN# 4 Ellen 30.0 CA 88.0 NaN# 5 Frank 30.0 NaN NaN NaN

pandas.Series

对于pandas.Series,可以与前面的示例相同的方式进行处理。

s = df['age']print(s)# 0 24.0# 1NaN# 2NaN# 3 68.0# 4NaN# 5 30.0# Name: age, dtype: float64print(s.fillna(100))# 024.0# 1 100.0# 2 100.0# 368.0# 4 100.0# 530.0# Name: age, dtype: float64print(s.fillna({1: 100, 4: 0}))# 024.0# 1 100.0# 2NaN# 368.0# 40.0# 530.0# Name: age, dtype: float64print(s.fillna(method='bfill', limit=1))# 0 24.0# 1NaN# 2 68.0# 3 68.0# 4 30.0# 5 30.0# Name: age, dtype: float64

提取缺失值

提取特定行/列中缺少值的列/行

如果要选择并检查特定列中包含缺失值的行,通过isull()方法,并通过布尔索引引用进行检查提取。

print(df)# name age state point other# 0 Alice 24.0 NY NaN NaN# 1NaN NaN NaN NaN NaN# 2 Charlie NaN CA NaN NaN# 3Dave 68.0 TX 70.0 NaN# 4 Ellen NaN CA 88.0 NaN# 5 Frank 30.0 NaN NaN NaNprint(df['point'].isnull())# 0True# 1True# 2True# 3 False# 4 False# 5True# Name: point, dtype: boolprint(df[df['point'].isnull()])# name age state point other# 0 Alice 24.0 NY NaN NaN# 1NaN NaN NaN NaN NaN# 2 Charlie NaN CA NaN NaN# 5 Frank 30.0 NaN NaN NaN

选择在特定行中包含缺失值的列时,想法是相同的。使用loc []按行名(行标签)选择,并使用iloc []按位置选择。请参见以下文章。

04_Pandas获取和修改任意位置的值(at,iat,loc,iloc)

print(df.iloc[2].isnull())# nameFalse# age True# state False# pointTrue# otherTrue# Name: 2, dtype: boolprint(df.loc[:, df.iloc[2].isnull()])#age point other# 0 24.0 NaN NaN# 1 NaN NaN NaN# 2 NaN NaN NaN# 3 68.0 70.0 NaN# 4 NaN 88.0 NaN# 5 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# 3Dave 68.0 TX 70.0# 4 Ellen NaN CA 88.0# 5 Frank 30.0 NaN NaN

pandas.DataFrame isnull()方法确定每个元素是否为缺失值,并返回为True或False的pandas.DataFrame。

print(df2.isnull())#name age state point# 0 False False False True# 2 False True False True# 3 False False False False# 4 False True False False# 5 False False True True

如果任何行或列包含True,则any方法将返回True。如果参数axis= 1,则在该行上执行处理。

print(df2.isnull().any(axis=1))# 0True# 2True# 3 False# 4True# 5True# dtype: boolprint(df2[df2.isnull().any(axis=1)])# name age state point# 0 Alice 24.0 NY NaN# 2 Charlie NaN CA NaN# 4 Ellen NaN CA 88.0# 5 Frank 30.0 NaN NaN

提取列时也是如此。如果any()的参数轴设置为0,则对列执行处理。可以省略,因为默认值为axis = 0。

print(df2.isnull().any())# nameFalse# age True# stateTrue# pointTrue# dtype: boolprint(df2.loc[:, df2.isnull().any()])#age state point# 0 24.0 NY NaN# 2 NaN CA NaN# 3 68.0 TX 70.0# 4 NaN CA 88.0# 5 30.0 NaN NaN

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。