读取带有垃圾值的错误的csv文件

时间:2018-12-24 12:16:24

标签: python pandas csv tokenize parse-error

我希望使用熊猫读取具有以下格式的csv文件:

    atrrth
    sfkjbgksjg
    airuqghlerig
    Name         Roll
    airuqgorqowi
    awlrkgjabgwl
    AAA          67
    BBB          55
    CCC          07

如您所见,如果我使用pd.read_csv,则会收到相当明显的错误:

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

但是我希望将整个数据放入一个数据帧中。使用error_bad_lines = False将删除重要内容,仅保留垃圾值

这些是可能的2个列名,如下所示:

Name : [Name , NAME , Name of student] 
Roll : [Rollno , Roll , ROLL]

如何实现?

3 个答案:

答案 0 :(得分:2)

打开csv文件,并从列名开始的地方找到一行:

with open(r'data.csv') as fp:
    skip = next(filter(
        lambda x: x[1].startswith(('Name','NAME')),
        enumerate(fp)
    ))[0]

该值将存储在skip参数中

import pandas as pd
df = pd.read_csv('data.csv', skiprows=skip)

在Python 3.X中工作

答案 1 :(得分:2)

我想建议对@RahulAgarwal's answer进行一些修改/简化。您可以直接将相同的流直接加载到熊猫中,而不必关闭并重新打开文件。您不必记录要跳过的行数,而可以记录标题行并对其进行手动拆分以提供列名:

with open(r'data.csv') as fp:
    names = next(line for line in fp if line.casefold().lstrip().startswith('name'))
    df = pd.read_csv(fp, names=names.strip().split())

这对于具有大量废纸lines的文件来说是一个优势。

更详细的检查可能是这样的:

def isheader(line):
    items = line.strip().split()
    if len(items) != 2:
        return False
    items = sorted(map(str.casefold, items))
    return items[0].startswith('name') and items[1].startswith('roll')

此功能将以任何顺序处理所有可能的情况,但当前也会跳过其中有空格的废纸lines。您可以将其用作过滤器:

names = next(line for line in fp if isheader(line))

答案 2 :(得分:0)

如果这确实是结构(而不​​只是一个例子,可以得到哪种垃圾),则可以简单地使用skiprows参数来指示应跳过多少行。换句话说,您应该像这样读取数据框:

import pandas as pd

df = pd.read_csv('your.csv', skiprows=3)

请注意,skiprows可以做的更多。检查文档。