数据的存储——CSV文件存储
1、CSV简介
CSV,全称叫做 Comma-Separated Values,中文可以叫做逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔,每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符,不过所有记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式,它相比 Excel 文件更加简介,XLS 文本是电子表格,它包含了文本、数值、公式和格式等内容,而 CSV 中不包含这些内容,就是特定字符分隔的纯文本,结构简单清晰,所以有时候我们用 CSV 来保存数据是比较方便的,本节我们来讲解下 Python 读取和写入 CSV 文件的过程。
2、导出数据为csv相比excel的优势
(1)把数据写成csv格式文件。
- csv文件可以直接用Excel打开。
- 写csv文件的效率和写txt文件的效率一样高。
- 同样的数据内容,生成的csv文件的大小远远小于生成的Excel文件。
从以上优点就可以看出生成csv文件消耗的内存绝对小于生成Excel文件。
(2)按一定的格式去生成csv文件,在Excel中打开的时候就是完整的行和列格式。
(3)同样的数据内容,csv文件和Excel文件的大小对比:
-
导出excel不能流式处理,导致占用比较大的内存,很容易导致内存溢出;并且excel的数据量是有限制的,不能超过65536行。一旦超过,将无法生成excel文件。
-
csv方式导出,则可以像导出txt一样,以文本流的方式进行流式处理,不但能导出海量信息,而且流式处理占用内存极低,服务器对浏览器的响应也是非常迅速的。轻松导出几百万行数据,理论上是不限量的。
不过,csv方式导出也存在问题:
首先,如果用excel来打开csv,超过65536行的数据都会看不见,这是excel程序的问题。
其次,如果你要导出一个身份证号码,手机号码,邮政编码等,纯数字构成的字符串,在excel中打开csv时,这些字段很容易被识别成数字,造成误解。我一般加上"\t",也有人加" ' "单引号 。
3、文件的写入
import csv with open('data.csv','w')as csvfile: writer =csv.writer(csvfile) writer.writerow(['id','name','age']) writer.writerow(['001', 'Tom', '21']) writer.writerow(['002', 'Jack', '22']) writer.writerow(['003', 'Make', '23'])
运行结束后会生成一个名为 data.csv 的文件,数据就成功写入了,直接文本形式打开的话内容如下:
id,name,age
001,Tom,21
002,Jack,22
003,Make,23
可以看到写入的文本默认是以逗号分隔的,调用一次 writerow() 方法即可写入一行数据,excel打开结果如图所示
可以使用 delimiter 参数来修改列与列之间的分隔符
import csv with open('data.csv','w')as csvfile: writer =csv.writer(csvfile,delimiter=' ')#注意delimiter这里的值必须有一个空格 writer.writerow(['id','name','age']) writer.writerow(['001', 'Tom', '21']) writer.writerow(['002', 'Jack', '22']) writer.writerow(['003', 'Make', '23'])
生成结果为
id name age
001 Tom 21
002 Jack 22
003 Make 23
可以看出使用空格而非逗号隔开
二维列表
另外也可以调用 writerows() 方法同时写入多行,此时参数就需要为二维列表
import csv with open('data.csv','w')as csvfile: writer =csv.writer(csvfile,delimiter=' ')#注意delimiter这里的值必须有一个空格 writer.writerow(['id','name','age']) writer.writerows([['001', 'Tom', '21'],['002', 'Jack', '22'],['003', 'Make', '23']])#注意这里是列表中套用列表
得到的结果和上面一样
id name age
001 Tom 21
002 Jack 22
003 Make 23
但是一般情况下爬虫爬取的都是结构化数据,我们一般会用字典来表示,在 csv 库中也提供了字典的写入方式,
import csv with open('data.csv','w')as csvfile: filednames=['id','name','age'] writer=csv.DictWriter(csvfile,fieldnames=filednames,delimiter=' ') writer.writeheader() writer.writerow({'id':'001','name':'Tom','age':21}) writer.writerow({'id': '002', 'name': 'Jack', 'age': 22}) writer.writerow({'id': '003', 'name': 'Make', 'age': 23})
这里先定义了三个字段,用 fieldnames 表示,然后传给 DictWriter 初始化一个字典写入对象,然后可以先调用 writeheader() 方法先写入头信息,然后再调用 writerow() 方法传入相应字典即可,最终写入的结果是完全相同的,内容如下:
id name age
001 Tom 21
002 Jack 22
003 Make 23
这样就完成了字典到 CSV 文件的写入。
此外还可以追加内容,具体代码如下
import csv with open('data.csv','a')as csvfile: filednames=['id','name','age'] writer=csv.DictWriter(csvfile,fieldnames=filednames,delimiter=' ') writer.writerow({'id':'004','name':'Jom','age':25})
结果如下
id name age
001 Tom 21
002 Jack 22
003 Make 23
004 Jom 25
如果写入的内容含有中文汉字,则需要注意编码格式
import csv with open('data.csv','w',encoding='utf-8')as csvfile:#后面有中文输入,所以这里需要定义编码格式为utf-8 filednames=['id','name','age'] writer=csv.DictWriter(csvfile,fieldnames=filednames,delimiter=' ') writer.writeheader() writer.writerow({'id': '001', 'name': 'Tom', 'age': 21}) writer.writerow({'id': '002', 'name': 'Jack', 'age': 22}) writer.writerow({'id': '003', 'name': 'Make', 'age': 23}) writer.writerow({'id': '004', 'name': 'Jom', 'age': 25}) writer.writerow({'id': '005', 'name': '张伟', 'age': 25})
读取
同样可以使用 csv 库来读取 CSV 文件,例如我们现在将刚才写入的文件内容读取出来,代码如下:
结果如下:
可以看出有很多空格,在使用excel文件打开csv文件后可以看出基本上都是跨行显示,具体解决办法是:newline=’‘,写入文件的代码如下
结果为
id,name,age 001,Tom,21 002,Jack,22 003,Make,23 004,Jom,25 005,张伟,25
行与行之间明显紧凑许多
则使用上面的代码重新读出文件,结果为
也不会出现空格出现
在这里我们构造的是 Reader 对象,通过遍历输出了每行的内容,每一行都是一个列表形式,注意在这里如果 CSV 文件中包含中文的话需要指定文件编码。
也可以使用 Pandas 库来操作
代码明显简洁许多,运行结果为
id name age 0 1 Tom 21 1 2 Jack 22 2 3 Make 23 3 4 Jom 25 4 5 张伟 25
在做数据分析的时候此种方法用的比较多,也是一种比较方便的读取 CSV 文件的方法。