我希望使用熊猫读取具有以下格式的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]
如何实现?
答案 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
可以做的更多。检查文档。