在 Pandas 中读取 CSV 文件时无法正常工作,sep='\t'

Reading a CSV file in Pandas not working properly with sep='\t'

提问人:sisseck.net 提问时间:11/13/2023 最后编辑:halfersisseck.net 更新时间:11/13/2023 访问量:75

问:

我有一堆来自 HPLC 的 CSV 文件,当通过 pandas.read_csv 进行标准导入时,我得到了这样的东西。

import pandas as pd
import glob

#get files from folder, careful, case sensitive

files = glob.glob('./*.txt')
df = pd.read_csv(files[0])
0   Application Name\tLabSolutions
1   Version\t5.93
2   Data File Name\tC:\LabSolutions\Data\outreach\...
3   Output Date\t11/12/2023
4   Output Time\t3:03:23 PM

但是当尝试将分隔符更改为制表符时df = pd.read_csv(files[0], sep='\t')

我明白了

---------------------------------------------------------------------------
ParserError                               Traceback (most recent call last)
<ipython-input-627-dc81386f301e> in <cell line: 8>()
      6 
      7 files = glob.glob('./*.txt')
----> 8 df = pd.read_csv(files[0], sep='\t')
      9 df

9 frames
/usr/local/lib/python3.10/dist-packages/pandas/_libs/parsers.pyx in pandas._libs.parsers.raise_parser_error()

ParserError: Error tokenizing data. C error: Expected 2 fields in line 73, saw 

可能出了什么问题?

这些文件的结构有点奇怪,部分定义如下。

[File Information]
Type    Data File
Generated   11/12/2023 9:51:47 AM
Generated by    Lab2
Modified    11/12/2023 2:58:18 PM
Modified by Lab2

[Configuration]
Instrument Name S24564-Instrument1
Instrument #    1
Line #  1
# of Detectors  2
Detector ID Detector A  Detector B
Detector Name   Detector A  Detector
# of Channels   2   1

像这样的几个不同的块,具有不同的数据行和列。

另一种选择是以某种方式获取每个文件的每个 [部分],但我更不知道如何处理它。

我忘记了我尝试过的内容,我不明白这如何导致错误,我所做的只是要求使用制表符而不是逗号作为分隔符。

Python Pandas 数据帧 CSV

评论

0赞 Matthias 11/13/2023
文件中是否真的有一个选项卡,或者它只是字符串“\t”。
0赞 alec_djinn 11/13/2023
您可以共享部分文件吗?您发布的示例不是 csv 格式。它看起来更像是配置文件,某种 YAML。

答:

2赞 ndclt 11/13/2023 #1

从错误中可以看出,文件的第 73 行只有一个字段,因此 a 不存在。\t

为了获得更多细节,我会使用这样的参数:on_bad_lines

import pandas as pd
import glob

#get files from folder, careful, case sensitive

files = glob.glob('./*.txt')
df = pd.read_csv(files[0], on_bad_lines='warn')

您应该能够拥有一个数据帧,并在日志中包含带有warings的行(但我想错误将与以前相同)。

参数的文档:on_bad_lines

on_bad_lines{'error', 'warn', 'skip'} 或 Callable,默认为“error”

指定遇到坏行(字段过多的行)时要执行的操作。允许的值为:

  • 'error',当遇到坏行时引发异常。
  • “警告”,在遇到坏行时发出警告并跳过该行。
  • “跳过”,跳过坏行,当遇到它们时不提出或警告。
2赞 Nick 11/13/2023 #2

处理此问题的一种方法是将文件读入不带分隔符的 pandas,然后在 上拆分生成的单列。如果需要,您可以删除任何没有两个值的行(例如节标题,例如):\t[Configuration]

df = pd.read_csv(files[0])
df = df[0].str.split('\t', expand=True)
df = df.dropna(subset=[1])

注意:我假设 csv 文件中没有标题,因此原始列将被标记;事实并非如此,只需替换其位置的实际列名即可。按照 ,您可以根据需要重命名列。0dropna

另请注意,看起来您可能有一些行中包含多个制表符分隔符,在这种情况下,将生成两列以上。如果不希望这样做,请指定限制为一次拆分:splitn=1

df = df[0].str.split('\t', n=1, expand=True)