使用numpy.genfromtxt读取带首部#注释文件触发IndexError如何解决
问题原因
np.genfromtxt的参数执行逻辑是:先无条件跳过文件开头skip_header指定的行数,再对剩余行做注释过滤、数据解析。
- 无开头注释时:你设置
skip_header=2刚好跳过前2行表头,剩余内容都是合法数据行/末尾注释行,解析正常。 - 有开头注释时:开头多了1行#注释,
skip_header=2会跳过「1行注释+第一行表头」,把第二行表头(单位行,非#开头)当成数据行解析,该行内容和你定义的17列dtype不匹配,直接触发IndexError。
末尾的#注释不会出问题,是因为数据解析完成后剩余的#开头行都会被自动过滤,不会进入解析逻辑。
解决方法
方法1:动态计算需要跳过的行数(推荐,兼容任意数量开头注释)
先读取文件统计开头#注释的行数,再动态设置skip_header的值:
import numpy as np file_path = 'omni low res 7-14 to 7-18.txt' # 统计开头#注释行数 comment_lines = 0 with open(file_path, 'r', encoding='utf-8') as f: for line in f: if line.strip().startswith('#'): comment_lines +=1 else: break # 总跳过行数=注释行数+2行表头 lowResOmni = np.genfromtxt(file_path, dtype=[('year', int), ('SOY', float) , ('B', float), ('Bx', float), ('By', float), ('Bz', float) , ('plasmaTemp', float), ('ionDensity', float), ('plasmaSpeed', float), ('plasmaPressure', float) , ('pFlux1', float), ('pFlux2', float), ('pFlux4', float), ('pFlux10', float) , ('DST', int), ('AL', int), ('AU', int)] , comments="#", skip_header=comment_lines + 2, usemask=True , missing_values={0:'', 1:'' , 2:999.9, 3:999.9, 4:999.9, 5:999.9 , 6:9999999., 7:999.9, 8:9999., 9:99.99 , 10:999999.99, 11:99999.99, 12:99999.99, 13:99999.99 , 14:99999, 15:99999, 16:99999})
方法2:手动过滤所有注释行后解析
如果不想额外做一次文件读取,也可以先把所有非注释行读出来,再喂给genfromtxt,跳过前2行表头即可:
with open(file_path, 'r', encoding='utf-8') as f: # 过滤所有#开头的行 valid_lines = [line for line in f if not line.strip().startswith('#')] lowResOmni = np.genfromtxt(valid_lines, dtype=[('year', int), ('SOY', float) , ('B', float), ('Bx', float), ('By', float), ('Bz', float) , ('plasmaTemp', float), ('ionDensity', float), ('plasmaSpeed', float), ('plasmaPressure', float) , ('pFlux1', float), ('pFlux2', float), ('pFlux4', float), ('pFlux10', float) , ('DST', int), ('AL', int), ('AU', int)] , skip_header=2, usemask=True , missing_values={0:'', 1:'' , 2:999.9, 3:999.9, 4:999.9, 5:999.9 , 6:9999999., 7:999.9, 8:9999., 9:99.99 , 10:999999.99, 11:99999.99, 12:99999.99, 13:99999.99 , 14:99999, 15:99999, 16:99999})
两种方法都不需要修改原始数据文件,不管开头有多少行#注释都可以正常解析。
内容的提问来源于stack exchange,提问作者root
相关产品推荐
相关产品推荐

