mysql导入csv文件少行原因探索
在 IT 审计的数据分析中,如果数据量稍微大点,获取数据我们一般都是 csv 文件。
如果客户给了很多 Excel 文件,我一般也会批量转成 csv 文件合并成一个,
再将数据导入到 Mysql 数据库中。
我自己在导完数后,一般会对行数进行校验,看原文件多少行,以及导入数据库多少行,确认数据导入正确。
昨天我发现导入数据库后的行数比 CSV 文件行数少,且没有报错。
其实之前我也遇到过两次这种问题,但当时数据量是上亿行和千万行,实在难以找到原因。
昨天的一个数据只有 4 万行,为了了解原因,用二分法经过大概 20 次数据对比,肉眼找到出问题的那行。
发现原因是字段内有换行符 。
换行符
这里我们举一个例子:
这张表里有两行数据,其中第二行“商品名称”中有换行符。
我们将数据导入到 mysql 数据库会看到也是只有两行
但是你用命令行wc -l
查看数据行数或者用记事本打开就会有 4 行数据:
这就是为什么我们查看 csv 的行数比我们导入数据库中的行数多的原因。
那么我们看看解决方法。
去除CSV文件中的换行符
我们可以使用 pandas 库读取 csv 文件,并用 replace 函数将换行符\n
替换为空。
import pandas as pd
df = pd.read_csv('数据.csv')
df = df.replace('\n', '', regex=True)
df.to_csv('数据_new.csv',index=False)
可以看到输出的文件中换行符被替换了。
当然,一般我们处理的数据会非常大,如果这样一次性读取会超过电脑内存,这时我们可以使用分块读取,分块处理。
import pandas as pd
def replace_newlines(input_file, output_file):
chunksize = 10**6 #1MB
flag = True
for chunk in pd.read_csv(input_file, chunksize=chunksize, engine='python'):
# Process each chunk
chunk = chunk.replace('\n', '', regex=True)
# write the chunk to the output_file
if flag:
chunk.to_csv(output_file,mode='w',header=True,index=False)
flag = False
else:
chunk.to_csv(output_file,mode='a',header=False,index=False)
if __name__ == "__main__":
replace_newlines('数据.csv','数据_pandas.csv')
我们可以看到数据也被正确处理了,当然,这里没有拿大数据来演示。
去除Excel文件的换行符
如果给的 Excel 文件,需要转成 CSV 文件,那么你仍然可以使用上面 pandas 的处理方法,区别只是读取 csv 文件变成了读取 excel 文件。
使用pd.read_excel()
即可读取 Excel 文件。如果想输出成 Excel ,可以使用pd.to_excel()
即可。
当然,我们还可以使用更简单的方法。
python有个xlsx2csv
库,可以直接将 Excel 转成 csv 文件。
安装方法:
pip install xlsx2csv
我们可以看到直接这样转换, csv 文件中还是会有换行符。
通过xlsx2csv --help
可以查看帮助文档。
我们可以看到有两个参数可以使用:
-e
:会将\r\n\t等符号变成字符串。
--no-line-breaks
:会将换行符替换成空格。
(注: windows 换行符为\r\n, Linux 换行符为\n)
因此我们只需要使用这两个参数即可。
结语
其实昨天如果不是为了找这个原因,也可以手工一个一个 excel 去导入。
但这样其实自己是没有任何收获的。
4万多行,二分法肉眼才找到出问题那行。
耗费了一晚上研究清楚这个问题产生原因,将来各种情况的解决方法,无疑以后再次遇到的时候将直接上手解决。
重剑无锋,大巧不工。