You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas读取多列.dat文件触发ParserError问题求助

解决pandas读取多列.dat文件触发的ParserError问题

作为Jupyter新手,你遇到的这个问题其实很常见——当数据文件列数变多后,pd.read_csv的空白分隔解析逻辑容易因为格式细节出问题。咱们一步步拆解原因和解决办法:

问题重现

你用CSV转成的.dat文件,4列时读取正常,列数增多就报错。你的核心代码和报错栈如下:

核心代码

import numpy as np
import pandas as pd
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.colors import ListedColormap, LinearSegmentedColormap

file1 = 'king2.dat'
file2 = 'iso.dat'
data1 = pd.read_csv(file1, delimiter='\s+', header=None, engine='python')
data1.columns = ['no_plt', 'Op_RA_plt', 'Op_DE_plt', 'Vmag_plt', 'B- V_plt', '(B-V)o_plt', 'no_2_plt', 'FUV_mag_plt','FUV_magerr_plt', '(FUV-V)_plt', '(V-I)_plt', '(FUV-I)_plt', 'no_op_2M','Op_RA_2M','Op_DE_2M','Vmag_2M','(B-V)o_2M', 'FUV_mag_2M','FUV-V_2M','no_2M','j_m_2M','h_m_2M','k_m_2M','j-h_2M', 'h-k_2M','j-k_2M','(V-I)_2M','(FUV-I)_2M', 'no_MS','Op_RA_MS','Op_DE_MS','Vmag_MS','(B-V)o_MS', 'FUV_mag_MS','FUV-V_MS','(V-I)_MS','(FUV-I)_MS', 'no_508','Op_RA_508','Op_DE_508','Vmag_508','(B-V)o_508', 'FUV_mag_508','FUV-V_508', '(V-I)_508','(FUV-I)_508', 'no_RG','Op_RA_RG','Op_DE_RG','Vmag_RG','(B-V)o_RG','FUV_mag_RG', 'FUV-V_RG','(V-I)_RG','(FUV-I)_RG','no_RG609','Op_RA_RG609', 'Op_DE_RG609','Vmag_RG609','(B-V)o_RG609','FUV_mag_RG609', 'FUV-V_RG609', '(V-I)_RG609', '(FUV-I)_RG609', 'no_TF621','Op_RA_TF621','Op_DE_TF621','Vmag_TF621','(B-V)o_TF621', 'FUV_mag_TF621','FUV-V_TF621','(V-I)_TF621','(FUV-I)_TF621', 'no_onBSS','Op_RA_onBSS','Op_DE_onBSS','Vmag_onBSS','(B-V)o_onBSS', 'FUV_mag_onBSS','FUV-V_onBSS','(V-I)_onBSs','(FUV-I)_onBSS', 'no_BSSreg','Op_RA_BSSreg','Op_DE_BSSreg','Vmag_BSSreg', '(B-V)o_BSSreg','FUV_mag_BSSreg','FUV-V_BSSreg','(V-I)_BSSreg', '(FUV-I)_BSSreg','no_BSSreg558', 'Op_RA_BSSreg558' , 'Op_DE_BSSreg558','Vmag_BSSreg558','(B-V)o_BSSreg558', 'FUV_mag_BSSreg558','FUV-V_BSSreg558','(V-I)_BSSreg558','(FUV-I)_BSSreg558','no_aMS','Op_RA_aMS', 'Op_DE_aMS','Vmag_aMS','(B-V)o_aMS','FUV_mag_aMS','FUV-V_aMS','(V-I)_aMS','(FUV-I)_aMS','no_bMS', 'Op_RA_bMS','Op_DE_bMS','Vmag_bMS','(B-V)o_bMS','FUV_mag_bMS','FUV-V_bMS','(V-I)_bMS', '(FUV-I)_bMS','no _SED','Op_RA _SED','Op_DE _SED','Vmag _SED','(B-V)o _SED','FUV_mag _SED', 'FUV-V _SED','(V-I)_SED','(FUV-I)_SED']
data2 = pd.read_csv(file1, delimiter='\s+', header=None, engine='python')
data2.columns =['age','log(Z)','mass','logl','logt','logg', 'FUVCa_14.76','NUVB15_14.76', '(FUV-NUV)14.76','V14.76','B14.76', 'B-V14.76','(FUV-V)14.76','(NUV-V)14.76','GA NUV14.76', '(Uf-Gn)14.76','I14.76','(V-I)14.76','(FUV-I)14.76']

def fit_data():
    fig = plt.figure(1,figsize=(8,8))
    plt.subplot(111)
    plt.scatter(data1['(B-V)o_plt'], data1['Vmag_plt'], marker='.', color='r', s=5)
    plt.scatter(data2['B-V14.76'], data2['V14.76'], marker='o', color='g', s=6)
    plt.xlabel('RA_F',size=20)
    plt.ylabel('DEC_F',size=20)
    plt.gca().invert_xaxis()
    plt.gca().invert_yaxis()
    plt.show()
    plt.close()

fit_data()

报错栈

ParserError Traceback (most recent call last)
<ipython-input-5-fe66f2a2aac9> in <module>()
     13 data1.columns = ['age','FUVCa','NUVB15','(FUV-NUV)','V','B','B-V','(FUV-V)','(NUV-V)','I','(V-I)','(FUV-I)']
     14 ---> 15 data2 = pd.read_csv(file2, delimiter='\s+', header=None, engine='python')
     16 data2.columns = ['no','Op_RA','Op_DE','Vmag','(B-V)o','FUV_mag','(FUV-V)','(V-I)','(FUV-I)', 'no_MS','Op_RA_MS','Op_DE_MS','Vmag_MS','(B-V)o_MS',
     17 'FUV_mag_MS','FUV-V_MS','(V-I)_MS','(FUV-I)_MS','no_508','Op_RA_508','Op_DE_508','Vmag_508',

~/anaconda3/lib/python3.6/site-packages/pandas/io/parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, escapechar, comment, encoding, dialect, tupleize_cols, error_bad_lines, warn_bad_lines, skipfooter, skip_footer, doublequote, delim_whitespace, as_recarray, compact_ints, use_unsigned, low_memory, buffer_lines, memory_map, float_precision)
    707 skip_blank_lines=skip_blank_lines)
    708 ---> 709 return _read(filepath_or_buffer, kwds)
    710
    711 parser_f.__name__ = name

~/anaconda3/lib/python3.6/site-packages/pandas/io/parsers.py in _read(filepath_or_buffer, kwds)
    453
    454 try:
--> 455 data = parser.read(nrows)
    456 finally:
    457 parser.close()

~/anaconda3/lib/python3.6/site-packages/pandas/io/parsers.py in read(self, nrows)
   1067 raise ValueError('skipfooter not supported for iteration')
   1068 -> 1069 ret = self._engine.read(nrows)
   1070
   1071 if self.options.get('as_recarray'):

~/anaconda3/lib/python3.6/site-packages/pandas/io/parsers.py ...

问题原因分析

  1. 分隔符匹配不稳定:delimiter='\s+'用来匹配任意数量的空白符,但当列数变多后,某行可能出现分隔符不一致(比如混合了空格和制表符,或者某列的值包含空格),导致解析时列数不匹配。
  2. 行格式不一致:大型数据文件容易存在异常行(比如空行、缺失部分列的行、格式错乱的行),列数少的时候可能刚好适配,列数多就暴露问题。
  3. Python引擎的解析限制:虽然指定了engine='python',但它处理超大量列时的容错性不如C引擎(不过C引擎不支持skipfooter等部分参数)。

解决方案

1. 先排查并跳过异常行

先确认文件里是否有坏行,用error_bad_lines=False跳过解析失败的行,同时warn_bad_lines=True让pandas提示哪些行有问题,方便后续修复:

data1 = pd.read_csv(file1, delimiter='\s+', header=None, engine='python', error_bad_lines=False, warn_bad_lines=True)

2. 改用更稳健的空白分隔参数

试试用delim_whitespace=True代替delimiter='\s+',这个参数是pandas专门为空白分隔文件设计的,解析逻辑更稳定:

data1 = pd.read_csv(file1, delim_whitespace=True, header=None, engine='python')

3. 提前指定列数,确保匹配

你已经手动指定了列名,但要确保列名的数量和文件实际的列数完全一致。如果不确定,可以先读取少量行查看列数:

# 先读10行看列数
temp_data = pd.read_csv(file1, delimiter='\s+', header=None, engine='python', nrows=10)
print(f"文件实际列数:{temp_data.shape[1]}")
# 再调整你的列名列表数量,确保和实际列数一致

4. 用numpy读取后转DataFrame

如果pandas的解析还是有问题,可以先用numpy的loadtxt读取(它对格式的容忍度更高),再转成DataFrame:

import numpy as np
# 读取数据,假设都是数值型,如果有字符串可以用dtype=object
data_np = np.loadtxt(file1)
data1 = pd.DataFrame(data_np)
# 再设置列名
data1.columns = ['no_plt', 'Op_RA_plt', ...]  # 你的完整列名列表

5. 检查数据文件的格式一致性

用命令行工具快速检查文件的行格式:

  • 查看所有行的列数是否一致:awk '{print NF}' king2.dat | sort -u(如果输出多个数字,说明有行列数不一致)
  • 查看前10行的格式:head -10 king2.dat,确认分隔符是否统一

调试小技巧

  • 先读取少量行测试,比如nrows=50,快速验证解析逻辑是否正常
  • 读取后打印前几行:print(data1.head()),确认列是否正确分隔

内容的提问来源于stack exchange,提问作者BRMBU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:00:31