问题背景
python支持的read_csv非常方便易用,但在一次把csv转为xlsx的简单应用过程中,发现有多列诸如**‘Skipping line 7: expected 2 fields, saw 3’**报错,检查具体文件,发现报错的行都缺失了。需要调查解决。
问题定位
1.常规思路搜报错
出现很多相似问题,但要么没有解决,要么可读性差。最终是从下面作者找到的方案:
python读取csv文件遇到的问题
我一开始甚至以为和我的不是一个问题而错过浪费了至少3小时。。。直到后来测试文件的行数可以被检查,才能发现根因。
2.根因分析
一开始一直以为是参数的问题,就像这个链接的老哥,参数准备得很齐全然而并没有什么用。。How to fix “skipping line” error when reading a file
在确认所有参数都无法帮助到我的时候,我又回过头仔细想了前一篇的思路,再拉报错来看,并一个一个检查了我的csv文件,最终破案。
首先,我的每一次执行报错都是相同的,必现问题,必然能解决。报错如下:
如果文件过多,从以上报错内容是非常难定位到哪个文件出问题的,幸好我的文件不多而且大部分行数少,所以很快找到了问题文件。用nodepad++打开如下:
可以看到报错的第3行和第8行的差异,结合谷歌翻译
这时候我Get到了,是首行索引列不足以匹配第N行索引列,导致python读取异常,打开转化后的文件看了,确实全文件转化后最多只有3列。
解决方案
这时候回过头再看第一篇老哥的思路,正是解决我这个问题的办法!但是!不得不说很戳!难道Python没有处理这种异常的能力吗?!我不信!但没时间去找其他解决办法了,就只好拿来大法先用着了。
def csv2xlsx(csv_file):
# 不是csv不处理
if not csv_file.endswith('.csv'):
return
# 切片获取文件名,上文判断了文件末尾是.csv
dst_filename = csv_file[:-4]
#在读取csv文件前,需要先获取文件所有行的最大行数Lmax,按最大行数读取数据
#在获取销售明细出现Skipping line 3错误,导致数据缺失。原因就是该文件前几行都是只有1~5个数值,read_csv按几个数值取值,但后面明细有几十个,不匹配导致读取失败。
with open(csv_file, encoding='UTF-8') as temp_f:
# get No of columns in each line
col_count = [len(l.split(",")) for l in temp_f.readlines()]
column_names = [i for i in range(max(col_count))]
pdata = pd.read_csv(csv_file, header=None, skip_blank_lines=True, names=column_names) #加入参数
#print(pdata)
if not os.path.isdir("Dst"):
# 不存在的话就创建子目录Dst
# 因为父目录存在,所有这里用mkdir也可以
os.makedirs("Dst")
if not os.path.isfile("Dst\\" + dst_filename + ".xlsx"):
# 无文件利用open创建,必须指定mode为写入模式
# mode默认是只读模式,无文件时不指定mode会报错
f = open("Dst\\" + dst_filename + ".xlsx", mode="w")
f.close()
else:
pass
pdata.to_excel("Dst\\" + dst_filename + ".xlsx",sheet_name="Sheet1", header = None, index=False) #header=None忽略首行引入的列索引
后记
估计是没时间找更优的解决方案了,但能找到临时方案也不错,谁叫自己菜呢。做好笔记,方便未来的自己和后来的菜鸡。