使用垃圾值读取错误的 csv 文件

Reading bad csv files with garbage values

我希望使用 pandas 读取具有以下格式的 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]

如何实现?

打开 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)

在Python3.X

工作

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

import pandas as pd

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

注意 skiprows 可以做更多的事情。检查文档。

我想建议 modification/simplification 到 @RahulAgarwal's answer。您可以继续将相同的流直接加载到 pandas,而不是关闭并 re-opening 文件。您可以记录 header 行并手动拆分以提供列名,而不是记录要跳过的行数:

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())

这对于包含大量垃圾行的文件有优势。

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

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')

此功能将以任何顺序处理您的所有可能性,但目前还会跳过其中包含空格的垃圾行。您可以将其用作过滤器:

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