我正在处理python中一个非常大的csv文件,其中一些行抛出了一个错误"'utf-8‘编解码器无法解码位置为7657的字节0x9b :无效的开始字节“。有没有一种方法可以跳过不是utf-8的行而不手动删除或修复数据?
for filename in filenames:
f = open(filename, 'rt')
reader = csv.reader(f, delimiter = ',')
for row in reader:
#process data for future use我不能使用非utf 8数据,因为后面的进程需要utf-8使用。
发布于 2015-05-15 17:55:04
您可以使用一个筛选器将一行读取为原始字节,然后尝试将其转换为unicode为UTF8,然后:
假设您使用的是Python2,您可以使用以下内容:
class MyFilter:
def __init__(self, instr, errstr):
self.instr = instr
self.errstr = errstr
def __enter__(self):
print("ENTERING filter")
return self
def __exit__(self, a, b, c):
print("EXITING filter")
self.instr.close()
self.errstr.close()
return False
def __next__(self):
line = next(self.instr)
while True:
try:
t = line.decode('utf8')
return line.strip()
except UnicodeDecodeError:
self.errstr.write(line)
line = next(self.instr)
return line
def __iter__(self):
return self
def next(self):
return self.__next__()然后,您可以这样使用它(假设Python2.7),在err.txt中获取所有违规行:
with open('file.csv') as istream, open("err.txt", 'w') as err, MyFilter(istream, err) as fd:
c = csv.reader(fd)
for i in c:
# do you stuff, eg: print i如果使用Python3,则可以使用几乎相同的筛选器类,只需将行return line.strip()替换为return t.strip(),以便返回字符串而不是字节。
用法也几乎相同:
with open('file.csv', 'rb') as istream, open("err.txt", 'wb') as err, MyFilter(istream, err) as fd:
c = csv.reader(fd)
for i in c:
# do you stuff, eg: print (i)根据您的注释,您还希望筛选包含空字符的行。这只需要在过滤器中稍加修改,while块就会变成(Python3版本):
while True:
if b'\x00' not in line:
try:
t = line.decode('utf8')
return t.strip()
except UnicodeDecodeError:
pass
self.errstr.write(line)
line = next(self.instr)https://stackoverflow.com/questions/30263434
复制相似问题