【问题标题】:ParserError: Expected 2 fields in line 32, saw 4ParserError:预计第 32 行中有 2 个字段,看到 4
【发布时间】:2020-08-24 09:24:46
【问题描述】:

我在解析 txt 文件时遇到问题(请参阅此处:File) 这是我的代码

import pandas as pd
objectname = r"path"
df = pd.read_csv(objectname, engine = 'python',  sep='\t', header=None)

不幸的是,它不起作用。由于这个问题已经被问过好几次了,我尝试了很多建议的解决方案(大部分都可以在这里找到:Possible solutions

但是,没有什么对我有用。例如,当我使用

sep='delimiter'

数据框已创建,但所有内容最终都在一个列中。

当我使用时

error_bad_lines=False

我感兴趣的行被简单地跳过了。

唯一可行的方法是我第一次打开 txt 文件,复制内容,将其粘贴到 Google 表格中,将文件另存为 CSV,然后打开数据框。

我想另一种解决方法是使用

df = pd.read_csv(objectname, engine = 'python',  sep = 'delimiter', header=None)

结合拆分功能Split function

是否有任何建议如何在不需要转换文件或使用拆分功能的情况下完成这项工作?我正在使用 Python 3 和 Windows 10。 任何帮助表示赞赏。

【问题讨论】:

  • 请提供您的文件示例(几行,而不是链接)。
  • Pandas 抱怨您的输入文件。这是说大多数行有 2 个值(2 列,如果你愿意的话),但是一行(第 32 行)有 4 个值(4 列)。我不打算从互联网上下载一些随机文件,但我的猜测是第 32 行缺少一个换行符,它将它分成两行,每行 2 列。

标签: python pandas windows csv parse-error


【解决方案1】:

您的文件有制表符分隔符,但不是 TSV。该文件是元数据的混合,然后是“标准”TSV,然后是更多元数据。因此,我发现将元数据作为与加载数据不同的任务是很有用的。

这是我提取元数据行的方法:

with open('example.txt','r') as file_handle:
    file_content = file_handle.read().split('\n')

for index, line in enumerate(file_content):
    if index<21 or index>37:
        print(index, line.split('\t'))

请注意,表示元数据开始和停止的行(在我的示例中为 21 和 37)是特定于文件的。我提供了我在下面使用的修剪数据(基于您的链接文件)。

另外,我将 TSV 加载到 Pandas 中使用

import pandas as pd
df = pd.read_csv('example.txt', engine = 'python',  
                 sep='\t', error_bad_lines=False, header=None,
                 skiprows=list(range(21))+list(range(37,89)))

同样,我跳过了文件开头和结尾处的元数据。

这是我试验过的文件。我已经修剪了额外的数据以减少行数。

TITLE   Test123
DATA TYPE   
ORIGIN  JASCO
OWNER   
DATE    19/03/28
TIME    16:39:44
SPECTROMETER/DATA SYSTEM    
LOCALE  1031
RESOLUTION  
DELTAX  -0,5
XUNITS  NANOMETERS
YUNITS  CD [mdeg]
Y2UNITS HT [V]
Y3UNITS ABSORBANCE
FIRSTX    300,0000
LASTX     190,0000
NPOINTS      221
FIRSTY      -0,78961
MAXY        37,26262
MINY       -53,38971
XYDATA
300,0000    -0,789606   182,198 -0,0205245
299,5000    -0,691644   182,461 -0,0181217
299,0000    -0,700976   182,801 -0,0136756
298,5000    -0,614708   182,799 -0,0131957
298,0000    -0,422611   182,783 -0,0130073
195,0000    26,6231 997,498 4,7258
194,5000    -17,3049    997,574 4,6864
194,0000    16,0387 997,765 4,63967
193,5000    -14,4049    997,967 4,58593
193,0000    -0,277261   998,025 4,52411
192,5000    -29,6098    998,047 4,45244
192,0000    -11,5786    998,097 4,36608
191,5000    34,0505 998,282 4,27376
191,0000    28,2325 998,314 4,1701
190,5000    -13,232 998,336 4,05036
190,0000    -47,023 998,419 3,91883

##### Extended Information
[Comments]
Sample name X
Comment
User
Division
Company RWTH Aachen

[Detailed Information]
Creation date   28.03.2019 16:39

Data array type Linear data array * 3
Horizontal axis Wavelength [nm]
Vertical axis(1)    CD [mdeg]
Vertical axis(2)    HT [V]
Vertical axis(3)    Abs
Start   300 nm
End 190 nm
Data interval   0,5 nm
Data points 221     

[Measurement Information]
Instrument name CD-Photometer
Model name  J-1100
Serial No.  A001361635

Detector    Standard PMT
  Lock-in amp.  X mode
  HT volt   Auto

Accessory   PTC-514
Accessory S/N   A000161648
  Temperature   18.63 C
  Control sonsor    Holder
  Monitor sensor    Holder

Measurement date    28.03.2019 16:39

Overload detect 203
Photometric mode    CD, HT, Abs
Measure range   300 - 190 nm
Data pitch  0.5 nm
CD scale    2000 mdeg/1.0 dOD
FL scale    200 mdeg/1.0 dOD
D.I.T.  0.5 sec
Bandwidth   1.00 nm
Start mode  Immediately
Scanning speed  200 nm/min
Baseline correction Baseline
Shutter control Auto
Accumulations   3

【讨论】:

  • 谢谢!帮了我很多。我(和其他人)如何确定文件中是否有元数据?我实际上只对 TSV 数据感兴趣。所以skiprows=list(range(21))+list(range(37,89))) 成功了。现在我只需要弄清楚如何自动检测元数据的开头和结尾,因为我有数百个这样的文件。
  • 通常元数据结构是一致的(如果文件都是由同一个程序生成的,这可能是预期的)。您可以通过手动检查一些示例 TSV 文件来确定是否是这种情况。例如,上层元数据块可能总是以XYDATA 结尾。如果这是真的,那么您只需要查看以字符串XYDATA 开头的行号并在该行之后收集数据。同样,我猜##### Extended Information 之后的行是较低的元数据块。
  • 谢谢,这里有一些自动提取TSV数据的代码:df = pd.read_csv(objectname, engine = 'python', sep = 'decimal', decimal=",")start = df.loc[df[df.columns[0]] == "XYDATA"].index[0]end = df.loc[df[df.columns[0]] == "##### Extended Information"].index[0]df1 = pd.read_csv(objectname, engine = 'python', sep = '\t', decimal=",", skiprows=list(range(start+2))+list(range(end+1,len(df)+9)), header = None)
猜你喜欢
  • 2020-11-02
  • 2020-12-10
  • 2021-02-10
  • 2018-03-14
  • 2020-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
相关资源
最近更新 更多