在 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 df1 和 df2。fillna()
会用 df2 中的相应值替换 df1 中的缺失值。
常见问题
我们可以先使用 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
值,因此它被删除了。
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
值的列。