Pandas删除列:如何从DataFrame中删除列
Updated on
来自真实数据源的DataFrame很少只包含你需要的列。CSV导出包含元数据列,数据库查询会拉取额外字段,API响应包含你已经展平的嵌套数据。在进行任何有意义的分析之前,你需要删除不相关的列。如果操作不当——不小心删除了错误的列,或者在打算创建副本时修改了原始DataFrame——就会导致难以追踪的数据丢失Bug。
Pandas提供了多种删除列的方法,每种方法适用于不同的情况。drop()方法最为通用,但del、pop()和列选择也提供了有用的替代方案。本指南通过清晰的示例介绍每种方法,展示何时使用哪种方法。
使用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 Charlieinplace参数
默认情况下,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 | 可选(inplace) | 是 | errors='ignore' |
del df[col] | 无 | 总是 | 否(逐个) | 引发KeyError |
df.pop(col) | 被删除的Series | 总是 | 否(逐个) | 引发KeyError |
df[cols_to_keep] | 新DataFrame | 否 | 是(反向) | 引发KeyError |
df.select_dtypes() | 新DataFrame | 否 | 按dtype | N/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()。