Pandas 处理缺失值

在 Pandas 中,缺失值,通常表示为 NaN(Not a Number),可能会在数据处理和分析过程中引起问题。这些数据中的空白可能导致错误的分析和误导性的结论。

Pandas 提供了一系列函数,如 dropna()fillna()combine_first() 来处理缺失值。

让我们考虑以下 DataFrame 来演示处理缺失数据的各种技术

import pandas as pd
import numpy as np

# create dataframe with missing values
data = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5],
    'D': [1, 2, 3, 4, 5]
}
df = pd.DataFrame(data)

print(df)

输出

     A    B    C  D
0  1.0  NaN  1.0  1
1  2.0  2.0  2.0  2
2  NaN  3.0  3.0  3
3  4.0  4.0  NaN  4
4  5.0  5.0  5.0  5

在这里,我们使用了 NumPy 库在 DataFrame 中生成 NaN 值。


删除包含缺失值的行

处理缺失值的一种直接方法是删除它们。由于我们处理的数据集通常很大,消除几行通常对最终结果影响很小。

我们使用 dropna() 函数来删除至少包含一个缺失值的行。例如,

import pandas as pd
import numpy as np

# create a dataframe with missing values
data = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5],
    'D': [1, 2, 3, 4, 5]
}
df = pd.DataFrame(data)

# remove rows with missing values df.dropna(inplace=True)
print(df)

输出

     A    B    C  D
1  2.0  2.0  2.0  2
4  5.0  5.0  5.0  5

在此示例中,我们使用 dropna() 删除了所有包含 NaN 值的行。dropna() 方法会检测包含 NaN 值的行并将其删除。

在这里,inplace=True 表示直接在原始 DataFrame 中进行更改。


替换缺失值

与删除包含缺失值的整行相比,我们可以使用 fillna() 将缺失值替换为指定的值。

让我们看一个例子。

import pandas as pd
import numpy as np

# create a dataframe with missing values
data = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5],
    'D': [1, 2, 3, 4, 5]
}
df = pd.DataFrame(data)

# replace missing values with 0 df.fillna(value=0, inplace=True)
print(df)

输出

     A    B    C  D
0  1.0  0.0  1.0  1
1  2.0  2.0  2.0  2
2  0.0  3.0  3.0  3
3  4.0  4.0  0.0  4
4  5.0  5.0  5.0  5

在此示例中,我们使用 fillna()NaN 值替换为 **0**。


用平均值、中位数和众数替换缺失值

一种更精细的方法是用列中剩余值的平均值、中位数或众数来替换缺失值。这比仅用默认值替换能提供更准确的表示。

我们可以使用带有聚合函数的 fillna() 函数将缺失值替换为平均值、中位数或众数。

让我们看一个例子。

import pandas as pd
import numpy as np

# create a dataframe with missing values
data = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5],
    'D': [1, 2, 3, 4, 5]
}
df = pd.DataFrame(data)

# replace missing values with mean df['A'].fillna(value=df['A'].mean(), inplace=True)
# replace missing values with median df['B'].fillna(value=df['B'].median(), inplace=True)
# replace missing values with mode df['C'].fillna(value=df['C'].mode()[0], inplace=True)
print(df)

输出

     A    B    C  D
0  1.0  3.5  1.0  1
1  2.0  2.0  2.0  2
2  3.0  3.0  3.0  3
3  4.0  4.0  1.0  4
4  5.0  5.0  5.0  5

在此示例中,我们将 A、B 和 C 列的缺失值分别替换为其平均值、中位数和众数。

在这里,mode()[0] 返回最常见的值。由于所有值具有相同的频率,因此它会返回该列的第一个值。


使用另一个 DataFrame 替换值

我们可以使用 fillna() 方法用另一个 DataFrame 中的值来替换一个 DataFrame 中的缺失值。

让我们看一个例子。

import pandas as pd
import numpy as np

# create a dataframe with missing values
data1 = {
    'A': [1, 2, np.nan, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5],
    'D': [1, 2, 3, 4, 5]
}
df1 = pd.DataFrame(data1)

# create datframe to fill the missing values with
data2 = {
    'A': [10, 20, 30, 40, 50],
    'B': [10, 20, 30, 40, 50],
    'C': [10, 20, 30, 40, 50],
    'D': [10, 20, 30, 40, 50]
}
df2 = pd.DataFrame(data2)

# replace missing values
df1.fillna(df2, inplace=True)

print(df1)

输出

      A     B     C  D
0   1.0  10.0   1.0  1
1   2.0   2.0   2.0  2
2  30.0   3.0   3.0  3
3   4.0   4.0  40.0  4
4   5.0   5.0   5.0  5

在这里,我们有两个 DataFrame df1df2fillna() 会用 df2 中的相应值替换 df1 中的缺失值。


常见问题

如何删除只包含 NaN 值的列?

我们可以先使用 isnull()all() 方法选择只包含 NaN 值的列,然后删除这些列。

让我们看一个例子。

import pandas as pd
import numpy as np

# create a DataFrame
data = {
    'A': [1, 2, 3, 4],
    'B': [5, 6, np.nan, np.nan],
    'C': [np.nan, np.nan, np.nan, np.nan],
    'D': [9, 10, 11, 12]
}
df = pd.DataFrame(data)

# check which columns contain only NaN values columns_with_nan = df.columns[df.isnull().all()] # drop the columns containing only NaN values df = df.drop(columns=columns_with_nan)
print(df)

输出

   A    B   D
0  1  5.0   9
1  2  6.0  10
2  3  NaN  11
3  4  NaN  12

这里,

  • df.columns[df.isnull().all()] - 返回所有值都为空的列的列表
  • df.drop() - 删除指定的列

由于 C 列只包含 NaN 值,因此它被删除了。

如何删除包含超出特定数量的 NaN 值的列?
import pandas as pd
import numpy as np

# create a DataFrame
data = {
    'A': [1, 2, 3, np.nan],
    'B': [5, 6, np.nan, np.nan],
    'C': [np.nan, np.nan, np.nan, 7],
    'D': [9, 10, 11, 12]
}
df = pd.DataFrame(data)

# set the threshold for the maximum number of NaN values allowed threshold = 2 # calculate the number of NaN values in each column nan_counts = df.isnull().sum() # remove columns that have more NaN values than the threshold columns_to_drop = nan_counts[nan_counts > threshold].index df = df.drop(columns=columns_to_drop)
print(df)

输出

     A    B   D
0  1.0  5.0   9
1  2.0  6.0  10
2  3.0  NaN  11
3  NaN  NaN  12

这里,

  • df.isnull().sum() - 返回一个包含每列 NaN 值计数的整数列表
  • nan_counts[nan_counts>threshold].index - 返回 NaN 计数超过阈值索引的列索引列表
  • df.drop() - 删除指定的列

上面的代码删除了包含两个以上 NaN 值的列。

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战