CSV ,全称为 Comma-Separated Values ,中文可以叫逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔。每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符。不过所有记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。它比 Excel 文件更加简洁, XLS 文本是电子表格,它包含了文本、数值、公式和格式等内容,而 CSV 中不包含这些内容,就是特定字符分割的纯文本,结构简单清晰。
这里先看一个最简单的例子:
import csv
with open('data.csv', 'w')as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['id', 'name', 'age'])
writer.writerow(['10001', 'Mike', 20])
writer.writerow(['10002', 'Bob', 22])
writer.writerow(['10003', 'Jordan', 21])
首先,打开 data.csv 文件,然后指定打开的模式为 w (即写入),获得文件句柄,随后调用 csv 库的 writer() 方法初始化写入对象,传入该句柄,然后调用 writerow() 方法传入每行的数据即可完成写入。
运行结束后,会生成一个 data.csv 的文件,此时数据就成功写入了,直接以文本形式打开的话,其内容如下:
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
我们可以发现每条记录中间都空了一行,这可不太好啊!那么如何解决这个问题呢?首先从 open 方法入手,我们先查看一下 open 方法,打开命令提示符输入 python 或 ipython 回车进交互式解释器环境。然后直接输入 help(open) 回车,如图所示。
首先看这个函数的原型, 1 个必选参数, 7 个默认参数,我们注意到其中一个默认参数是 newline ,引起上面的结果出现空行可能就是因为它了,我们往下滑,找到对 newline 参数的解释,如图所示。
稍微翻译一下, newline 控制全局的换行如何工作(它仅仅应用于文本模式)。它可以是None,‘’,‘\n’,‘\r’ 和 ‘\r\n’。它按照如下方式工作:
简直是云里雾里啊~!这里看不懂没有关系,我们去看一下 csv 的官方文档(https://docs.python.org/3/library/csv.html#id3),找到如图所示的位置。
上面是 csv 模块的 writer 的函数原型,稍微翻译一下下面一段:
返回一个编写器对象,负责将用户的数据转换为给定类似文件的对象上的分隔字符串。 csvfile 可以是任何拥有写方法的对象。如果 csvfile 是一个文件对象,它应该伴随着 newline 参数为空字符串的过程被打开。……为什么呢?点击上面的 [1] 跳到最下面的注释部分,如图所示。
如果 newline=‘’ 没有被规定,嵌入在引号字段中的换行符将无法正确解释,并且在使用 \r\n 行尾的平台上将添加额外的 \r 。由于 csv 模块遵循它自己的换行处理标准,规定 newline=‘’ 总归是安全的。
按照官方文档所说的内容,我们修改上面的例子。
import csv
with open('data.csv', 'w', newline='')as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['id', 'name', 'age'])
writer.writerow(['10001', 'Mike', 20])
writer.writerow(['10002', 'Bob', 22])
writer.writerow(['10003', 'Jordan', 21])
再次运行一下,然后去看看文件内容,其内容如下:
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
终于成功了!可以看到,写入的文本默认以逗号分隔,调用一次 writerow() 方法即可写入一行数据。用 Excel 打开的结果如图所示。
如果想修改列与列之间的分隔符,可以传入 delimiter 参数,其代码如下:
import csv
with open('data.csv', 'w', newline='')as csvfile:
writer = csv.writer(csvfile, delimiter=' ')
writer.writerow(['id', 'name', 'age'])
writer.writerow(['10001', 'Mike', 20])
writer.writerow(['10002', 'Bob', 22])
writer.writerow(['10003', 'Jordan', 21])
在这里初始化写入对象时传入 delimiter 参数为空格,此时输出结果的每一列就是以空格分隔了,内容如下:
id name age
10001 Mike 20
10002 Bob 22
10003 Jordan 21
另外,我们也可以调用 writerows() 方法写入多行,此时参数就需要为二维列表,例如:
import csv
with open('data.csv', 'w', newline='')as csvfile:
writer = csv.writer(csvfile)
writer.writerow(['id', 'name', 'age'])
writer.writerows([['10001', 'Mike', 20], ['10002', 'Bob', 22], ['10003', 'Jordan', 21]])
输出效果是相同的,内容如下:
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
但是一般情况下,爬虫爬取的都是结构化数据,我们一般会用字典来表示。在 csv 库中也提供了字典的写入方式,示例如下:
import csv
with open('data.csv', 'w', newline='')as csvfile:
fieldnames = ['id', 'name', 'age']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'id': '10001', 'name': 'Mike', 'age': 20})
writer.writerow({'id': '10002', 'name': 'Bob', 'age': 22})
writer.writerow({'id': '10003', 'name': 'Jordan', 'age': 21})
这里先定义 3 个字段,用 fieldnames 表示,然后将其传给 DictWriter 来初始化一个字典写入对象,接着可以调用 writeheader() 方法先写入头信息,然后再调用 writerow() 方法传入相应字典即可。最终写入的结果是完全相同的,内容如下:
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
这样就可以完成字典到 csv 文件的写入了。
另外,如果想追加写入的话,可以修改文件的打开模式,即将 open() 函数的第二个参数改成 a ,代码如下:
import csv
with open('data.csv', 'a', newline='')as csvfile:
fieldnames = ['id', 'name', 'age']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writerow({'id': '10004', 'name': 'Durant', 'age': 22})
这样在上面的基础上再执行这段代码,文件内容便会变成:
id,name,age
10001,Mike,20
10002,Bob,22
10003,Jordan,21
10004,Durant,22
可见,数据被追加写到文件中。
如果要写入中文内容的话,可能会遇到字符编码的问题,此时需要给 open 参数指定编码格式。比如,这里再写入一行包含中文的数据,代码需要改写如下:
import csv
with open('data.csv', 'a', encoding='utf-8', newline='')as csvfile:
fieldnames = ['id', 'name', 'age']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writerow({'id': '10005', 'name': '王伟', 'age': 22})
这里需要给 open() 函数指定编码,否则可能发生编码错误。
另外,如果接触过 pandas 等库的话,可以调用 DataFrame 对象的 to_csv() 方法来将数据写入 CSV 文件中。
我们同样可以使用 csv 库来读取 CSV 文件。例如,将刚才写入的文件内容读出来,相关代码如下:
import csv
with open('data.csv', 'r', encoding='utf-8')as csvfile:
reader = csv.reader(csvfile)
for row in reader:
print(row)
运行结果如下:
['id', 'name', 'age']
['10001', 'Mike', '20']
['10002', 'Bob', '22']
['10003', 'Jordan', '21']
['10004', 'Durant', '22']
['10005', '王伟', '22']
这里我们构造的是 Reader 对象,通过遍历输出了每行的内容,每一行都是一个列表形式。注意,如果 CSV 文件包含中文的话,还需要指定文件编码。
另外,如果接触过 pandas 的话,可以利用 read_csv() 方法将数据从 CSV 中读取出来,例如:
import pandas as pd
df = pd.read_csv('data.csv')
print(df)
运行结果如下:
我们可以发现中文没有对齐,感觉有点怪怪的~!我们首先需要知道为什么没有对齐。它之所以没有对齐,是因为它以最长的字符串为标准进行右对齐的,同时又因为汉字是宽字符(占用两个字符的位置),它现在还是以为中文汉字只有占一个字符位。如何解决这个问题呢?其实很简单,设置属性 display.unicode.ambiguous_as_wide 和 display.unicode.east_asian_width ,将这两个属性都设置为 True 即可,代码如下:
import pandas as pd
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_csv('data.csv')
print(df)
运行结果如下:
在做数据分析的时候,此种方法用的比较多,也是一种比较方便地读取 CSV 文件的方法。
我们了解了 CSV 文件的写入和读取方式。这也是一种常用的数据存储方式,需要熟练掌握。
本文分享自 Python机器学习算法说书人 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有