如何使用Python的csv.DictReader读取含同名/相似名列的CSV文件
处理含相似/重复列名的第三方CSV文件(基于csv.DictReader)
问题场景
获取了第三方提供的不可修改的CSV文件,存在两个核心问题:
- 列名相似:不同CSV文件的相似列名不固定(比如CSV A有
Column2[en]/Column2[us],CSV B有Column2[fr]/Column2[en]) - 列名重复:部分列名重复出现(比如
isPartOf列在两个示例CSV里都出现两次)
示例CSV文件
CSV File A
File Name,Column2[en],Column2[us],isPartOf,isPartOf file1.tif,English,US English,USA,North America file2.tif,English,,USA, file3.tif,,US,,North America
CSV File B
File Name,Column2[fr],Column2[en],isPartOf,isPartOf
疑问与测试
想知道:
- 能否用
csv.DictReader结合startswith()读取多列?还是需要先创建表头映射? - 能否读取同名列的所有数据?(禁止使用Pandas)
测试代码及运行结果:
#!/bin/env python3 import csv with open("./test.csv") as csv_file: csv_reader = csv.DictReader(csv_file, delimiter=',') for row in csv_reader: print(row["isPartOf"],row["isPartOf"])
运行命令:
$ ./csvReader.py North America North America North America
注:测试结果中,row["isPartOf"]仅能获取重复列的最后一列值,无法拿到所有同名列数据。
解决方案
1. 用startswith()读取相似列(无需提前做表头映射)
直接遍历csv_reader.fieldnames(表头列表),筛选出符合前缀条件的列名,再逐个提取对应行的数据即可。
示例代码:
import csv with open("./test.csv") as csv_file: csv_reader = csv.DictReader(csv_file, delimiter=',') # 筛选所有以"Column2["开头的列 target_cols = [col for col in csv_reader.fieldnames if col.startswith("Column2[")] for row in csv_reader: print(f"文件: {row['File Name']}") for col in target_cols: print(f" {col}: {row[col]}")
运行CSV A的输出:
文件: file1.tif Column2[en]: English Column2[us]: US English 文件: file2.tif Column2[en]: English Column2[us]: 文件: file3.tif Column2[en]: Column2[us]: US
2. 读取同名列的所有数据(需绕过csv.DictReader的覆盖机制)
csv.DictReader会自动覆盖同名列的值,仅保留最后一列的内容。要获取所有同名列数据,需改用csv.reader手动处理表头和行数据,把同名列的值存入列表:
示例代码:
import csv with open("./test.csv") as csv_file: csv_reader = csv.reader(csv_file, delimiter=',') headers = next(csv_reader) # 获取表头 # 找出所有重复列名的位置,这里以"isPartOf"为例 target_col_indices = [i for i, header in enumerate(headers) if header == "isPartOf"] for row in csv_reader: print(f"文件: {row[headers.index('File Name')]}") # 提取所有"isPartOf"列的值 is_part_of_values = [row[i] for i in target_col_indices] print(f" isPartOf列表: {[val for val in is_part_of_values if val]}") # 过滤空值
运行CSV A的输出:
文件: file1.tif isPartOf列表: ['USA', 'North America'] 文件: file2.tif isPartOf列表: ['USA'] 文件: file3.tif isPartOf列表: ['North America']
如果需要同时处理相似列和重复列,可以结合两种思路:先通过表头筛选目标列,再用csv.reader提取对应位置的数据。
内容的提问来源于stack exchange,提问作者jjohnson
相关产品推荐
相关产品推荐

