在数据分析工作中,我们经常会遇到需要从Pandas的DataFrame里挑选某些列,或者数据中存在多个同名列需要一并提取的情况。如果只按常规方式写代码,重名列很容易被忽略或覆盖,导致后续统计结果偏差。掌握正确的选择方法,是保证数据完整性的基础。

一、选择指定列的基本方式
最直观的做法是把列名放进一个列表,传给DataFrame的中括号或loc方法。这种方式简单明了,适合列名已知且不存在重复的场景。需要注意的是,返回的是原数据的视图还是副本,会影响后续赋值操作的行为。
下面示例展示如何从一个包含用户信息的表中选出姓名和年龄两列:
import pandas as pd
data = {
'name': ['张三', '李四', '王五'],
'age': [28, 34, 22],
'city': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
# 选择指定列
selected = df[['name', 'age']]
print(selected)
上述代码会输出一个仅包含name和age的新DataFrame。如果列名不存在,Pandas会抛出KeyError,因此动态选择时最好先判断列是否在df.columns中。另外,使用loc可以同时按行标签和列名筛选,写法为df.loc[:, ['name', 'age']],在链式操作中更安全。
二、识别并选择所有重复列
当DataFrame出现重复列名时,例如多次合并数据导致同列被追加,直接用df[['col']]只能拿到最后一列。要提取所有重名列,需要先从columns对象中找出重复标签,再借助loc的位置索引能力。
Pandas的Index对象提供了duplicated方法,可以标记哪些标签是重复出现的。结合这个特性,我们能构造一个布尔数组,筛选出所有重名列的位置。
import pandas as pd
# 构造含有重复列名的DataFrame
data = {
'score': [90, 85],
'score': [88, 92],
'age': [20, 21]
}
# 注意字典同键会覆盖,改用列表方式
df = pd.DataFrame([
[90, 88, 20],
[85, 92, 21]
], columns=['score', 'score', 'age'])
# 找出重复列名对应的位置
dup_mask = df.columns.duplicated(keep=False)
dup_cols = df.loc[:, dup_mask]
print(dup_cols)
代码中keep=False表示把所有重复项都标记为True,因此dup_mask是一个全True或False的序列,对应重名列的位置。df.loc[:, dup_mask]会按位置返回这些列,即使它们同名也能完整保留。运行后可以看到两个score列都被提取出来,不会发生丢失。
如果只想保留第一次出现的重名列,可以把keep改为first;若只关心最后一次出现的,则用last。这种灵活性让我们在清洗时能精确控制数据范围,而不必提前重命名列。
三、综合实践:指定列与重复列混合处理
实际任务里,我们可能既要拿某些固定列,又要附带所有重名列。此时可以分别生成列索引再合并,避免多次切片带来的混乱。下面的例子演示如何选出age列以及全部score重名列。
import pandas as pd
df = pd.DataFrame([
[90, 88, 20],
[85, 92, 21]
], columns=['score', 'score', 'age'])
# 固定列
wanted = ['age']
# 重复列掩码
dup_mask = df.columns.duplicated(keep=False)
# 合并索引
cols_to_take = wanted + list(df.columns[dup_mask])
result = df[cols_to_take]
print(result)
这里先把需要的固定列名放进列表,再通过df.columns[dup_mask]拿到重名列的标签序列,拼接后一次性切片。这样做逻辑清晰,也方便封装成函数。要注意如果wanted里的列本身也是重名,上述写法可能会重复选取,此时可用集合去重。
从性能角度看,基于columns的布尔掩码非常轻量,即便在几十万行的框上也不会成为瓶颈。比起先转置再处理,直接操作列索引更符合Pandas的设计习惯,也减少了不必要的内存拷贝。
四、常见误区与规避
一个容易被忽视的点是:用字典创建DataFrame时,同键会被覆盖,因此测试重复列必须像前面那样用列表加columns参数。另一个误区是以为df['score']会返回所有重名列,其实它只返回最后一列,这和数据直观感受相悖。
建议在数据读取阶段就检查列名情况,例如打印df.columns.value_counts()观察是否有大于1的值。提前发现重复,比在建模前才排查要省事得多。若确定某些重名列无用,也可在读取时通过mangle_dupe_cols参数让Pandas自动加后缀,但这会改动原列名,需权衡。
import pandas as pd
df = pd.DataFrame([
[90, 88, 20],
[85, 92, 21]
], columns=['score', 'score', 'age'])
# 查看列名重复情况
print(df.columns.value_counts())
上面这段代码会输出每个列名出现的次数,score对应2,说明存在重复。把它放在预处理日志里,可以快速预警。掌握这些技巧后,无论是日常报表还是特征工程,都能更稳妥地操作Pandas数据框。
PandasDataFrameduplicate_columns修改时间:2026-08-03 04:48:16