如果數(shù)據(jù)庫(kù)有特殊字符(換行符,轉(zhuǎn)義符),會(huì)導(dǎo)致生成的csv無(wú)法正常導(dǎo)入。
val1,val2,val3
aa,bb,cc
a
a,bb,cc
aa
,bb,cc
aa,
bb,cc
a\a,bb,cc
第一行header和第二行數(shù)據(jù)正常。
第三行第一個(gè)列有換行符,此時(shí)導(dǎo)致第四行看著正常(3列),但是數(shù)據(jù)又是錯(cuò)誤的。
第五行跟第三行類(lèi)似
第七行實(shí)際是第二個(gè)單元格首字符換行,導(dǎo)致第八行缺失一列。
第九行有轉(zhuǎn)義符
處理成
val1,val2,val3
aa,bb,cc
aa,bb,cc
aa,bb,cc
aa,bb,cc
aa,bb,cc
利用空閑時(shí)間,用python寫(xiě)了個(gè)修補(bǔ)工具,原理是利用,csv是從上往下讀的,如果前一行列數(shù)不夠,一定可以從后一列補(bǔ)上。但是可能存在補(bǔ)完后超過(guò)指定列(比如列內(nèi)包含分隔符,導(dǎo)致數(shù)據(jù)庫(kù)3列,變成4列),所以需要對(duì)其切片,只保留指定列數(shù)。
clean_csv.py
# -*- coding: utf-8 -*-
# Author AnJia(anjia0532@gmail.com https://anjia0532.github.io)
import argparse
import sys, os
import io
reload(sys)
sys.setdefaultencoding('utf8')
black_dict={"\\":"","\"":""}
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--cols', type=int, dest='cols', action='store', default=-1,help="count of columns,default first line's cells")
parser.add_argument('--src', type=str, dest='src', action='store', default='',
help='path to source csv file')
parser.add_argument('--dest', type=str, dest='dest', action='store', default='',
help='path to dest csv file')
parser.add_argument('--encoding', type=str, dest='encoding', action='store', default='utf-8',
help='file encoding,default utf-8')
parser.add_argument('--chunksize', type=int, dest='chunksize', action='store', default='10000',
help='batch lines to write dest file,default 10000')
parser.add_argument('--delimiter', type=str, dest='delimiter', action='store', default=',',
help='csv delimiter,default ,')
args = parser.parse_args()
cols = args.cols
src = args.src
dest = args.dest
encoding = args.encoding
chunksize = args.chunksize
delimiter = args.delimiter
if not (src and dest) or chunksize = 0:
print("invaild args!")
sys.exit(-1)
olds=[]
lines=[]
with io.open(src,encoding=encoding) as fp:
for line in fp.readlines():
line = line.strip()
for k,v in black_dict.items():
if k in line:
line=line.replace(k,v)
cells = line.split(delimiter)
if cols == -1:
cols=len(cells)
if(len(cells) cols or (len(olds)>0 and len(olds) cols)):
if not olds:
olds = cells
else:
cells[0]=olds[-1]+cells[0]
olds.pop()
olds.extend(cells)
if len(olds) >= cols:
cells=olds
olds=[]
if not olds:
lines.append(delimiter.join(cells[0:cols])+"\n")
if len(lines) % chunksize == 0:
write_to_file(dest=dest,lines=lines)
lines=[]
write_to_file(dest=dest,lines=lines)
def write_to_file(dest,lines=[],encoding='utf-8'):
p = os.path.split(dest)[0]
if not os.path.exists(p):
os.makedirs(p)
with io.open(file=dest,mode="a+",encoding=encoding) as fp:
fp.writelines(lines)
if __name__ == '__main__':
main()
使用方式
python clean_csv.py --src=src.csv --dest=dest.csv --chunksize=50000 --cols --encoding=utf-8 --delimiter=,
總結(jié)
以上所述是小編給大家介紹的csv文件容錯(cuò)處理方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
您可能感興趣的文章:- 解決Python中pandas讀取*.csv文件出現(xiàn)編碼問(wèn)題
- python 讀取.csv文件數(shù)據(jù)到數(shù)組(矩陣)的實(shí)例講解
- python的pandas工具包,保存.csv文件時(shí)不要表頭的實(shí)例
- PHP 實(shí)現(xiàn)從數(shù)據(jù)庫(kù)導(dǎo)出到.csv文件方法