趋近智
数据集经常含有空缺,在 Pandas 中表示为 NaN(非数字)。处理这些空缺的一个直接方法是简单地移除包含它们的行或列。这通常是一个合理的初步操作,特别是当你的数据中只有很小一部分缺失,或者某个特定行或列有太多缺失值以至于缺乏信息时。
Pandas 为此提供了 dropna() 方法。我们来了解它的用法。
默认情况下,如果行中任何值是 NaN,dropna() 会移除整行。
请看这个示例 DataFrame:
import pandas as pd
import numpy as np
data = {'col1': [1, 2, np.nan, 4, 5],
'col2': [np.nan, 7, 8, 9, 10],
'col3': [11, 12, 13, 14, np.nan],
'col4': ['A', 'B', 'C', 'D', 'E']}
df = pd.DataFrame(data)
print("原始 DataFrame:")
print(df)
Output:
原始 DataFrame:
col1 col2 col3 col4
0 1.0 NaN 11.0 A
1 2.0 7.0 12.0 B
2 NaN 8.0 13.0 C
3 4.0 9.0 14.0 D
4 5.0 10.0 NaN E
现在,我们使用 dropna() 的默认设置:
df_dropped_rows = df.dropna() # Default is axis=0 (rows) and how='any'
print("\n删除包含任何 NaN 的行后的 DataFrame:")
print(df_dropped_rows)
Output:
删除包含任何 NaN 的行后的 DataFrame:
col1 col2 col3 col4
1 2.0 7.0 12.0 B
3 4.0 9.0 14.0 D
请注意,行 0、2 和 4 被移除了,因为它们都至少包含一个 NaN 值。只有行 1 和 3 被保留,它们在所有列中都含有完整数据。
dropna() 方法有参数 (parameter),可以让你更精细地控制:
how 参数:
how='any'(默认):如果行中存在任何 NaN 值,则删除该行。how='all':仅当该行中的所有值都是 NaN 时,才删除该行。我们创建一个 DataFrame,其中有一行完全是 NaN:
data_with_all_nan = {'col1': [1, np.nan, np.nan, 4],
'col2': [np.nan, 7, np.nan, 9],
'col3': [11, 12, np.nan, 14]}
df_all_nan = pd.DataFrame(data_with_all_nan)
print("\n可能包含全 NaN 行的原始 DataFrame:")
print(df_all_nan)
df_dropped_all = df_all_nan.dropna(how='all')
print("\n删除所有 NaN 行后的 DataFrame:")
print(df_dropped_all)
Output:
可能包含全 NaN 行的原始 DataFrame:
col1 col2 col3
0 1.0 NaN 11.0
1 NaN 7.0 12.0
2 NaN NaN NaN
3 4.0 9.0 14.0
删除所有 NaN 行后的 DataFrame:
col1 col2 col3
0 1.0 NaN 11.0
1 NaN 7.0 12.0
3 4.0 9.0 14.0
在这种情况下,当使用 how='all' 时,只有所有值都是 NaN 的行 2 被删除了。
thresh 参数:这允许你指定一行要保留所需的非缺失值的最小数量。例如,thresh=3 意味着一行只有在至少有 3 个有效(非 NaN)值时才会被保留。
使用我们原始的 df:
# 保留至少有 3 个非 NaN 值的行
df_thresh3 = df.dropna(thresh=3)
print("\n保留至少有 3 个非 NaN 值的行后的 DataFrame:")
print(df_thresh3)
Output:
保留至少有 3 个非 NaN 值的行后的 DataFrame:
col1 col2 col3 col4
0 1.0 NaN 11.0 A # 已保留 (3 个非 NaN)
1 2.0 7.0 12.0 B # 已保留 (4 个非 NaN)
2 NaN 8.0 13.0 C # 已保留 (3 个非 NaN)
3 4.0 9.0 14.0 D # 已保留 (4 个非 NaN)
4 5.0 10.0 NaN E # 已保留 (3 个非 NaN)
在这里,所有行都被保留了,因为每行都至少有 3 个非缺失值。如果我们增加阈值:
# 保留至少有 4 个非 NaN 值的行
df_thresh4 = df.dropna(thresh=4)
print("\n保留至少有 4 个非 NaN 值的行后的 DataFrame:")
print(df_thresh4)
Output:
保留至少有 4 个非 NaN 值的行后的 DataFrame:
col1 col2 col3 col4
1 2.0 7.0 12.0 B
3 4.0 9.0 14.0 D
现在,只保留了行 1 和行 3,因为它们是唯一具有 4 个有效值的行。
有时,如果列中含有缺失数据,你可能希望移除整个列,特别是当一列有许多 NaN 值或对你的分析不重要时。你可以通过将 axis 参数 (parameter)设置为 1(或 'columns')来实现此操作。
# 删除包含任何 NaN 值的列
df_dropped_cols = df.dropna(axis=1) # axis=1 targets columns
print("\n删除包含任何 NaN 的列后的 DataFrame:")
print(df_dropped_cols)
Output:
删除包含任何 NaN 的列后的 DataFrame:
col4
0 A
1 B
2 C
3 D
4 E
在我们的示例 df 中,列 col1、col2 和 col3 都至少包含一个 NaN,因此它们被删除了。只有 col4 被保留,因为它没有缺失值。
当应用于列时,how 和 thresh 参数的用法类似:
df.dropna(axis=1, how='all') 会仅当列中所有值都是 NaN 时才删除该列。df.dropna(axis=1, thresh=4) 会仅当列中至少有 4 个非 NaN 值时才保留该列。# 保留至少有 4 个非 NaN 值的列
df_thresh4_cols = df.dropna(axis=1, thresh=4)
print("\n保留至少有 4 个非 NaN 值的列后的 DataFrame:")
print(df_thresh4_cols)
Output:
保留至少有 4 个非 NaN 值的列后的 DataFrame:
col1 col2 col3 col4
0 1.0 NaN 11.0 A
1 2.0 7.0 12.0 B
2 NaN 8.0 13.0 C
3 4.0 9.0 14.0 D
4 5.0 10.0 NaN E
在这种情况下,col1、col2 和 col3 各有 4 个非 NaN 值(总共 5 行),col4 有 5 个。由于所有都达到了 4 的阈值,因此没有列被删除。
默认情况下,dropna() 返回一个新的 DataFrame,其中缺失值已被删除,而原始 DataFrame 保持不变。如果你想直接修改原始 DataFrame,可以使用 inplace=True 参数 (parameter)。
df_copy = df.copy() # 创建一个副本进行修改
print("\n就地删除前的 DataFrame:")
print(df_copy)
df_copy.dropna(inplace=True) # 直接修改 df_copy
print("\n就地删除后的 DataFrame:")
print(df_copy)
Output:
就地删除前的 DataFrame:
col1 col2 col3 col4
0 1.0 NaN 11.0 A
1 2.0 7.0 12.0 B
2 NaN 8.0 13.0 C
3 4.0 9.0 14.0 D
4 5.0 10.0 NaN E
就地删除后的 DataFrame:
col1 col2 col3 col4
1 2.0 7.0 12.0 B
3 4.0 9.0 14.0 D
请谨慎使用 inplace=True。由于它直接修改你的数据,除非你确定不再需要包含 NaN 值的原始数据,否则通常更安全的方法是将结果赋给一个新变量。
删除缺失数据很简单,但它有代价:你会丢失信息。
这种策略通常最适用在以下情况:
在移除数据之前,务必考量其潜在影响。如果删除看起来过于严厉,下一节将介绍一个替代方案:填充缺失值。
这部分内容有帮助吗?
dropna方法的官方文档,详细说明了其参数、行为以及从DataFrame中删除缺失数据的各种方式。© 2026 ApX Machine Learning用心打造