pd.read_csv()默认将首行作为列名,需设header=None禁用;若CSV有真实列名则勿用该参数;skiprows与header组合使用时需注意行索引逻辑;处理带注释或BOM的文件需额外指定encoding或手动跳过。 pd.read_csv() 默认把首行当列名,怎么关掉 相信不少朋友
相信不少朋友都遇到过这个经典问题:打开一个没有表头的CSV文件,结果pd.read_csv()二话不说,直接把第一行数据当成了列名,导致后续所有数据都错位了一行。这事儿其实不怪数据,根源在于header这个参数的默认设置——它默认为0,意味着Pandas会“自作主张”地把第0行(也就是文件的第一行)解读为列标题。
解决起来并不复杂,关键在于明确告诉Pandas:“这个文件没有表头”。方法就是显式指定header=None:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
import pandas as pd
df = pd.read_csv("data.csv", header=None)
这样一来,Pandas就不会再去解析首行了,所有行都会被视作数据,同时它会自动生成一套整数列名,比如0, 1, 2...。
header=None,那么原本的列名就会变成第一行数据,后续你想用df["col_name"]来选取列时,就会触发KeyError。header=None常和names参数搭档使用,比如手动传入names=["id", "name", "score"]来赋予数据有意义的列名。skiprows=1来曲线救国——它虽然跳过了第一行,但默认行为依然会把新的首行(原第二行)当作列名,很容易造成二次混乱。当skiprows和header两个参数同时出现时,它们之间的配合就有点微妙了,很容易让人困惑。举个例子,假设文件前两行是说明文字,第三行才是真正的列名,该怎么设置?
skiprows=2的意思是:跳过原始文件中索引为0和1的两行(即前两行)。header应该设为0(指向这个新的首行),而header=0恰恰是默认值,所以通常可以省略。header=2,问题就来了:这个“2”指的是在原始文件中找第2行作列名,可前面已经跳过了2行,列名和数据就彻底对不上了。所以,正确的写法应该是:
df = pd.read_csv("report.csv", skiprows=2, header=0)
由于header=0是默认值,下面这种更简洁的写法是完全等价的:
df = pd.read_csv("report.csv", skiprows=2) # header=0 是默认值
如果觉得Pandas的封装太重,或者你需要更精细地控制行处理逻辑(比如首行是以#开头的注释),那么回归Python标准库的csv模块,反而会更加灵活可控:
import csv
with open("log.csv") as f:
reader = csv.reader(f)
next(reader) # 手动跳过第一行
for row in reader:
print(row)
next(reader)一句就能手动跳过首行,逻辑清晰,不依赖任何隐式约定。csv.reader不会进行自动类型转换,所有字段读进来都是字符串。后续如果需要数值计算,得自己手动处理,比如int(row[0])。itertools.dropwhile,或者写个循环判断if not line.strip().startswith("#")来过滤。这类“首行被误读”的问题可不是CSV的专利。当你使用pd.read_excel()时,同样存在header参数,默认值也是0。如果Excel文件的第一行是标题说明而非真正的列名,同样会导致数据错位。
header参数的默认行为,然后根据文件实际情况,决定是设为None、0还是其他行索引。pd.read_json()虽然没有header参数,但如果数据是records格式且包含一些冗余字段,就需要通过orient参数或数据预处理来过滤。"id")。解决方法是指定encoding="utf-8-sig"来正确解码。说到底,真正棘手的往往不是“如何跳过首行”这个动作本身,而是跳过之后,列名的对齐、数据类型的推断是否准确。尤其是遇到混合类型列(比如某一列里数字和空字符串混杂),Pandas可能统一推断为object类型,为后续的计算埋下静默失败的隐患。这才是需要额外警惕的地方。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述