应先用python原生读取文件前几行观察真实分隔符模式,再选择合适方式解析;pandas read_csv()虽支持正则分隔符,但需先确认空格、竖线、波浪线或混合符号等实际分隔类型。

识别分隔符类型比硬编码更可靠
直接用 sep=',' 或 sep='\t' 读取非标准文本,大概率会报错或解析错乱。Pandas 的 read_csv() 其实支持正则分隔符,但前提是得先确认真实分隔模式——空格、多个空格、竖线 |、波浪线 ~、甚至混合符号(如 || 或 ^A)都可能出现。
推荐做法是先用 Python 原生读取几行,观察规律:
with open('data.txt') as f:
for i, line in enumerate(f):
if i
<p>输出类似 <code>'ID|NAME|AGE|CITY\n'</code> 或 <code>'1 Alice 28 Beijing\n'</code>,就能判断该用 <code>sep='|'</code> 还是 <code>sep=r'\s+'</code>(匹配一个及以上空白字符)。</p>
- 若分隔符含特殊正则字符(如
|、+、*),必须加regex=True参数,否则会被当作字面量处理 -
sep=r'\s+'适合列间空格不一致的场景,但会把字段内空格也吃掉,慎用于含空格的字符串字段 - 若分隔符是 ASCII 控制字符(如
\x01,即 ^A),要用sep='\x01',不能写成sep='^A'
处理固定宽度格式不用 sep 参数
有些“非标准分隔”其实根本没分隔符,而是靠列位置对齐(如银行日志、旧系统导出文件)。这时 sep 无效,必须用 read_fwf()。
关键不是猜宽度,而是生成准确的 colspecs:
- 用文本编辑器打开文件,开启“显示空白字符”,观察每列起止列号
- 手动列出元组列表,例如
colspecs=[(0,5), (6,15), (16,18), (19,30)] - 如果列宽统一(如每列 10 字符),可用
widths=[10,10,10]简化 - 务必设
header=None,否则第一行会被误判为列名而跳过
跳过干扰行和脏数据头尾
实际文本常混着注释、统计行、空行或分隔线(如 -----),read_csv() 默认全读,导致 ValueError: Expected x fields in line y。
-
skiprows接整数跳前 N 行,接列表跳指定行号(从 0 开始) -
skipfooter=1(需配engine='python')可跳末尾 1 行,但不支持多行;更稳的方式是先用pd.read_csv(..., nrows=1000)试读,再用原生读取确定有效行范围 - 遇到以
#开头的注释行,加comment='#',它会自动跳过整行 - 若首行是列名但带多余空格或符号(如
"Name | Age | City"),别急着删,先用names参数手动指定列名,再设header=0避免重复解析
编码与缺失值处理容易被忽略
中文环境里最常卡在 UnicodeDecodeError: 'gbk' codec can't decode byte,这不是分隔符问题,是编码没对上。
- 先用
chardet检测:chardet.detect(open('data.txt','rb').read()),结果可能是{'encoding': 'utf-8-sig', 'confidence': 0.99} -
encoding='utf-8-sig'能自动去掉 BOM,比纯utf-8更稳妥 - 若字段含空值但未用统一占位符(如
N/A、NULL、-),需提前用na_values告诉 Pandas 哪些算缺失,否则会被当字符串保留 - 特别注意:
keep_default_na=False会禁用 Pandas 默认的['', '#N/A', 'NULL']等识别,仅当你明确要保留这些字符串时才设
真正麻烦的不是分隔符本身,而是同一份文件里混着多种格式逻辑——比如前 10 行是元数据,后面才是表格;或者某列数值里夹着单位符号(如 "123kg")。这种得拆开处理,别指望单次 read_csv() 解决所有问题。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











