数据的存储——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 文件,例如我们现在将刚才写入的文件内容读取出来,代码如下:

 

import csv
with open('data.csv','r',encoding='utf-8')as csvfile:#后面有中文输入,所以这里需要定义编码格式为utf-8
    reader=csv.reader(csvfile)
    for row in reader:
        print(row)

结果如下:

['id', 'name', 'age']
[]
['001', 'Tom', '21']
[]
['002', 'Jack', '22']
[]
['003', 'Make', '23']
[]
['004', 'Jom', '25']
[]
['005', '张伟', '25']
[]

可以看出有很多空格,在使用excel文件打开csv文件后可以看出基本上都是跨行显示,具体解决办法是:newline=’‘,写入文件的代码如下

import csv
with open('data.csv','w',newline='',encoding='utf-8')as csvfile:#后面有中文输入,所以这里需要定义编码格式为utf-8;如果这里没有newline这个参数的话,那么结果就会跨行显示
    filednames=['id','name','age']
    writer=csv.DictWriter(csvfile,fieldnames=filednames)
    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})

结果为

id,name,age
001,Tom,21
002,Jack,22
003,Make,23
004,Jom,25
005,张伟,25

行与行之间明显紧凑许多

则使用上面的代码重新读出文件,结果为

['id', 'name', 'age']
['001', 'Tom', '21']
['002', 'Jack', '22']
['003', 'Make', '23']
['004', 'Jom', '25']
['005', '张伟', '25']

也不会出现空格出现

在这里我们构造的是 Reader 对象,通过遍历输出了每行的内容,每一行都是一个列表形式,注意在这里如果 CSV 文件中包含中文的话需要指定文件编码。

也可以使用 Pandas 库来操作

import pandas as pd
df=pd.read_csv('data.csv')
print(df)

代码明显简洁许多,运行结果为

   id  name  age
0   1   Tom   21
1   2  Jack   22
2   3  Make   23
3   4   Jom   25
4   5    张伟   25

在做数据分析的时候此种方法用的比较多,也是一种比较方便的读取 CSV 文件的方法。

 

 

 

 

 

 

 

 
posted @ 2019-05-25 20:43  舒畅123  阅读(3021)  评论(0编辑  收藏  举报