read_csv默认跳过第一行是因为header=0将首行识别为列名;若CSV无真实列名,应设header=None并可配names指定列名,或修复BOM等源文件问题。
read_csv 为什么默认跳过第一行
因为 pandas.read_csv 默认把第一行当列名(header=0),如果你的 csv 实际上没有列名,或者第一行是真实数据,它就会被误判成表头丢掉。
常见错误现象:df.shape[0] 比原始文件行数少 1,打开 CSV 确认第一行存在但没进 DataFrame。
- 检查是否真没列名:用文本编辑器或
head -n 1 data.csv看第一行内容 - 如果第一行是数字、日期或明显是数据(比如
123,45.6,2023-01-01),那就必须关掉自动识别列名 - 别依赖 Excel 双击打开后的“视觉印象”——它可能自动加了表头样式,但 CSV 文件本身没这东西
header=None 是最直接的解法
加这个参数,pandas 就不会尝试从文件里猜列名,而是给每列分配默认名 0, 1, 2...,第一行也作为数据读进来。
import pandas as pd
df = pd.read_csv("data.csv", header=None)注意:header=None 和 header=0(默认)是互斥的;设成 None 后,names 参数才真正起作用——你可以手动指定列名:
df = pd.read_csv("data.csv", header=None, names=["id", "value", "date"])- 如果后续要按列名操作(比如
df["value"]),务必配names=...,否则只能用df[1]这种数字索引 -
header=None会禁用所有基于列名的解析逻辑,比如index_col如果写列名就失效,得改用数字位置
header=0 但想保留第一行?别硬绕
有人试过设 header=1 或 skiprows=0,结果更糟——前者让第二行变列名,后者根本没效果。本质问题在于:你不能一边告诉 pandas “第一行是 header”,一边又想留着它。
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
真要保留且带列名,只有两个干净做法:
- 用
header=None读入,再用df.iloc[0]提取第一行,手动塞进df.columns,然后用df = df.iloc[1:].reset_index(drop=True)——但这就等于自己实现一遍带 header 的逻辑,容易出索引错 - 更稳的做法:确认原始 CSV 是否真的该有列名。如果其实是有的,只是格式不标准(比如空格、中文括号、BOM 头),优先修源文件或加
encoding/skipinitialspace
Excel 导出的 CSV 常带隐藏坑
Windows 上用 Excel 另存为 CSV(UTF-8),可能在文件开头插入 BOM(\ufeff),导致 pandas 把第一列名读成 '\ufeff列名',看着像“第一行丢了”,其实是列名带不可见字符,后续 df["列名"] 报 KeyError。
验证方法:用 Python 打开看前几个字节:
with open("data.csv", "rb") as f:
print(f.read(5)) # 如果输出 b'\xef\xbb\xbf...' 就是 BOM- 解决:加
encoding="utf-8-sig",这个编码会自动剥离 BOM - 别用
encoding="utf-8"硬扛,BOM 会残留在列名里 - Mac / Linux 下用 Numbers 或 LibreOffice 导出的 CSV 一般没这问题,但 Windows Excel 是重灾区
复杂点往往不在参数选哪个,而在你根本没意识到文件本身被悄悄动过手脚。

















