如何查看pandas列名与列表值类型并统一实现列匹配筛选
pandas按列表筛选CSV读取的DataFrame列返回空的解决方法
问题场景
手动构造的测试DataFrame中,使用如下逻辑可正常筛选出目标列:
import pandas as pd data={'3123':[1,2,3], '5342':[3,2,4], '2039':[8,3,6], '1398':[2,8,8], '9854':[6,2,1], '8834':[3,7,0] } df=pd.DataFrame(data) df # 3123 5342 2039 1398 9854 8834 #0 1 3 8 2 6 3 #1 2 2 3 8 2 7 #2 3 4 6 8 1 0 list1= ['3123', '5342', '8834'] # 筛选代码 print(df[[i for i in list1 if i in df.columns]])
预期输出为:
# 3123 5342 8834 #0 1 3 3 #1 2 2 7 #2 3 4 0
但读取CSV文件生成DataFrame后,相同逻辑返回空DataFrame,即使列表值和列名文本完全一致。
根本原因
手动构造DataFrame时列名被明确定义为字符串类型,和列表内的字符串元素可正常匹配;pandas读取CSV时会自动推断列名类型,若列名为纯数字内容,会默认将列名转为整数类型,和列表内的字符串值类型不匹配,导致in判断全部返回False,最终筛选结果为空。
类型排查方法
执行以下代码可分别确认列名和列表元素的类型:
- 查看DataFrame所有列名的类型:
print(df.columns.map(type))
- 查看筛选列表内所有元素的类型:
print([type(i) for i in list1])
对比两边输出即可确认类型差异。
解决方法
方法1:统一列名为字符串类型(推荐)
读取CSV后直接将所有列名转为字符串,和手动构造数据的类型保持一致,原有筛选逻辑可直接复用:
df = pd.read_csv("your_file.csv") # 列名统一转字符串 df.columns = df.columns.astype(str) list1 = ['3123', '5342', '8834'] # 原有筛选逻辑可用 res = df[[i for i in list1 if i in df.columns]] # 也可以用更简洁的内置筛选方法,自动跳过不存在的列 res = df.loc[:, df.columns.isin(list1)] print(res)
方法2:统一列表元素类型和列名一致
如果不需要修改列名类型,可将筛选列表的元素转为和列名相同的类型,例如列名为整数时,将列表元素转为整数:
df = pd.read_csv("your_file.csv") list1 = ['3123', '5342', '8834'] # 列表元素转整数,匹配整数类型列名 list1_converted = [int(i) for i in list1] res = df[[i for i in list1_converted if i in df.columns]] print(res)
提示:如果筛选列表中可能包含DataFrame不存在的列名,不要直接使用
df[list1]的写法,否则会触发KeyError,使用列表推导过滤或df.columns.isin()的写法可自动忽略不存在的列。
内容的提问来源于stack exchange,提问作者Ssong
相关产品推荐
相关产品推荐

