Skip to content

Pandas删除列:如何从DataFrame中删除列

Updated on

来自真实数据源的DataFrame很少只包含你需要的列。CSV导出包含元数据列,数据库查询会拉取额外字段,API响应包含你已经展平的嵌套数据。在进行任何有意义的分析之前,你需要删除不相关的列。如果操作不当——不小心删除了错误的列,或者在打算创建副本时修改了原始DataFrame——就会导致难以追踪的数据丢失Bug。

Pandas提供了多种删除列的方法,每种方法适用于不同的情况。drop()方法最为通用,但delpop()和列选择也提供了有用的替代方案。本指南通过清晰的示例介绍每种方法,展示何时使用哪种方法。

📚

使用df.drop()——标准方法

drop()方法是删除列的主要方式。传入列名并设置axis=1(或使用columns参数)。

删除单列

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'salary': [50000, 60000, 70000],
    'department': ['Engineering', 'Marketing', 'Sales'],
})
 
# 方法1:使用columns参数(推荐)
df_clean = df.drop(columns=['salary'])
print(df_clean)
 
# 方法2:使用axis=1
df_clean = df.drop('salary', axis=1)

删除多列

import pandas as pd
 
df = pd.DataFrame({
    'id': [1, 2, 3],
    'name': ['Alice', 'Bob', 'Charlie'],
    'email': ['a@test.com', 'b@test.com', 'c@test.com'],
    'temp_col': [None, None, None],
    'internal_id': ['X1', 'X2', 'X3'],
})
 
# 一次删除多列
df_clean = df.drop(columns=['temp_col', 'internal_id', 'email'])
print(df_clean)
#    id     name
# 0   1    Alice
# 1   2      Bob
# 2   3  Charlie

inplace参数

默认情况下,drop()返回一个新的DataFrame。使用inplace=True来修改原始DataFrame:

import pandas as pd
 
df = pd.DataFrame({'a': [1], 'b': [2], 'c': [3]})
 
# 返回新DataFrame(原始不变)
new_df = df.drop(columns=['b'])
print(df.columns.tolist())      # ['a', 'b', 'c'](不变)
print(new_df.columns.tolist())  # ['a', 'c']
 
# 修改原始DataFrame
df.drop(columns=['b'], inplace=True)
print(df.columns.tolist())  # ['a', 'c']

使用errors参数处理不存在的列

import pandas as pd
 
df = pd.DataFrame({'a': [1], 'b': [2], 'c': [3]})
 
# 默认:如果列不存在则引发KeyError
# df.drop(columns=['d'])  # KeyError: "['d'] not found in axis"
 
# 忽略不存在的列
df_clean = df.drop(columns=['b', 'd'], errors='ignore')
print(df_clean.columns.tolist())  # ['a', 'c']

使用del语句

del语句就地(in-place)删除列。简洁但一次只能删除一列。

import pandas as pd
 
df = pd.DataFrame({'a': [1, 2], 'b': [3, 4], 'c': [5, 6]})
 
del df['b']
print(df.columns.tolist())  # ['a', 'c']

限制: 不能一次删除多列。不能忽略不存在的列(引发KeyError)。总是就地修改。

使用df.pop()

pop()删除一列并将其作为Series返回。当你需要被删除的列作后续使用时很有用。

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'target': [1, 0],
    'feature1': [10, 20],
    'feature2': [30, 40],
})
 
# 提取目标列同时将其从DataFrame中删除
y = df.pop('target')
X = df
 
print(y)
# 0    1
# 1    0
# Name: target, dtype: int64
 
print(X)
#     name  feature1  feature2
# 0  Alice        10        30
# 1    Bob        20        40

选择列(删除的反向操作)

有时选择你想要的列比列出要删除的列更容易。

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'age': [25, 30],
    'salary': [50000, 60000],
    'dept': ['Eng', 'Mkt'],
    'internal_id': ['X1', 'X2'],
})
 
# 只保留特定列
df_clean = df[['name', 'age', 'salary']]
 
# 通过选择除目标列外的所有列来删除
df_clean = df.loc[:, df.columns != 'internal_id']
 
# 保留满足条件的列
df_numeric = df.select_dtypes(include='number')
print(df_numeric)
#    age  salary
# 0   25   50000
# 1   30   60000

按模式或条件删除列

按名称模式删除列

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice'], 'age': [25],
    'temp_1': [None], 'temp_2': [None],
    'internal_flag': [True],
})
 
# 删除以'temp_'开头的列
cols_to_drop = [c for c in df.columns if c.startswith('temp_')]
df_clean = df.drop(columns=cols_to_drop)
print(df_clean.columns.tolist())  # ['name', 'age', 'internal_flag']
 
# 删除包含'internal'的列
cols_to_drop = [c for c in df.columns if 'internal' in c]
df_clean = df.drop(columns=cols_to_drop)
 
# 使用filter()保留匹配的列
df_temps = df.filter(like='temp')  # 只保留包含'temp'的列
df_no_temps = df.drop(columns=df.filter(like='temp').columns)

按数据类型删除列

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob'],
    'age': [25, 30],
    'score': [95.5, 87.3],
    'active': [True, False],
})
 
# 删除所有非数值列
df_numeric = df.select_dtypes(include='number')
 
# 删除所有object(字符串)列
df_no_strings = df.select_dtypes(exclude='object')
print(df_no_strings.columns.tolist())  # ['age', 'score', 'active']

删除缺失值过多的列

import pandas as pd
import numpy as np
 
df = pd.DataFrame({
    'a': [1, 2, 3, 4, 5],
    'b': [1, np.nan, np.nan, np.nan, np.nan],
    'c': [1, 2, np.nan, 4, 5],
    'd': [np.nan, np.nan, np.nan, np.nan, np.nan],
})
 
# 删除超过50%值缺失的列
threshold = len(df) * 0.5
df_clean = df.dropna(axis=1, thresh=int(threshold))
print(df_clean.columns.tolist())  # ['a', 'c']

方法比较

方法返回值就地修改多列缺失列处理
df.drop(columns=...)新DataFrame可选(inplaceerrors='ignore'
del df[col]总是否(逐个)引发KeyError
df.pop(col)被删除的Series总是否(逐个)引发KeyError
df[cols_to_keep]新DataFrame是(反向)引发KeyError
df.select_dtypes()新DataFrame按dtypeN/A

可视化清理后的DataFrame

删除列并清理数据后,PyGWalker (opens in a new tab)提供了一个交互式的Tableau风格界面,可以直接在Jupyter中探索清理后的DataFrame:

import pygwalker as pyg
 
# 清理DataFrame后
walker = pyg.walk(df_clean)

这让你可以通过拖放剩余列来构建图表,无需编写任何绑图代码。

FAQ

如何在Pandas中删除列?

使用df.drop(columns=['列名'])删除列并返回新DataFrame。就地删除添加inplace=True。也可以使用del df['列名']快速就地删除,或df.pop('列名')删除并将列作为Series返回。

如何一次删除多列?

将列名列表传给df.drop(columns=['col1', 'col2', 'col3'])。这会在一次操作中删除所有指定列并返回新DataFrame。

如何条件性地删除列(按模式或数据类型)?

对于名称模式,使用列表推导式:df.drop(columns=[c for c in df.columns if c.startswith('temp_')])。对于数据类型,使用df.select_dtypes(exclude='object')删除字符串列,或df.select_dtypes(include='number')只保留数值列。

drop()和del删除列有什么区别?

df.drop()默认返回新DataFrame,可以同时处理多列,并有errors='ignore'选项处理不存在的列。del df[col]总是就地修改,一次只能处理一列,列不存在时引发KeyError

如何删除有缺失值的列?

使用df.dropna(axis=1)删除至少有一个NaN的列。使用df.dropna(axis=1, thresh=n)只保留至少有n个非空值的列。自定义阈值可按空值百分比过滤:df.loc[:, df.isnull().mean() < 0.5]保留缺失数据低于50%的列。

总结

大多数情况下,df.drop(columns=[...])是正确的选择——它明确、处理多列,并默认返回新DataFrame。快速就地删除单列用del,需要被删除的列时用pop(),当指定保留什么比指定删除什么更容易时,使用列选择或select_dtypes()

📚