前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CSV文件存储

CSV文件存储

作者头像
不可言诉的深渊
发布2019-07-26 17:19:15
5.1K0
发布2019-07-26 17:19:15
举报

CSV ,全称为 Comma-Separated Values ,中文可以叫逗号分隔值或字符分隔值,其文件以纯文本形式存储表格数据。该文件是一个字符序列,可以由任意数目的记录组成,记录间以某种换行符分隔。每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符。不过所有记录都有完全相同的字段序列,相当于一个结构化表的纯文本形式。它比 Excel 文件更加简洁, XLS 文本是电子表格,它包含了文本、数值、公式和格式等内容,而 CSV 中不包含这些内容,就是特定字符分割的纯文本,结构简单清晰。

写入

这里先看一个最简单的例子:

代码语言:javascript
复制
  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 的文件,此时数据就成功写入了,直接以文本形式打开的话,其内容如下:

代码语言:javascript
复制
  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’。它按照如下方式工作:

  • 在输入时,如果 newline 是 None ,全局的换行模式是可用的,输入中的行可以以 ‘\n’,‘\r’ 或者 ‘\r\n’ 结尾,并且在被返回给调用者之前,这些会被解释成 ‘\n’ 。如果它是空字符串,全局换行模式也是可用的,但是每一行的结束符都会原封不动的返回给调用者。如果它有其他任何合法的值,输入的行仅仅按照被传入的字符串来终止,并且行的结束符被原封不动的返回给调用者。
  • 在输出时,如果 newline 是 None ,任何被写入的 ‘\n’ 字符会被解释成系统默认的行分隔符, os.linesep 。如果 newline 是 ‘’ 或者 ‘\n’ ,就没有解释发生。如果 newline 是任何其他合法的值,任何被写入的 ‘\n’ 字符被解释给传入的字符串。

简直是云里雾里啊~!这里看不懂没有关系,我们去看一下 csv 的官方文档(https://docs.python.org/3/library/csv.html#id3),找到如图所示的位置。

上面是 csv 模块的 writer 的函数原型,稍微翻译一下下面一段:

返回一个编写器对象,负责将用户的数据转换为给定类似文件的对象上的分隔字符串。 csvfile 可以是任何拥有写方法的对象。如果 csvfile 是一个文件对象,它应该伴随着 newline 参数为空字符串的过程被打开。……为什么呢?点击上面的 [1] 跳到最下面的注释部分,如图所示。

如果 newline=‘’ 没有被规定,嵌入在引号字段中的换行符将无法正确解释,并且在使用 \r\n 行尾的平台上将添加额外的 \r 。由于 csv 模块遵循它自己的换行处理标准,规定 newline=‘’ 总归是安全的。

按照官方文档所说的内容,我们修改上面的例子。

代码语言:javascript
复制
  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])

再次运行一下,然后去看看文件内容,其内容如下:

代码语言:javascript
复制
  id,name,age
  10001,Mike,20
  10002,Bob,22
  10003,Jordan,21

终于成功了!可以看到,写入的文本默认以逗号分隔,调用一次 writerow() 方法即可写入一行数据。用 Excel 打开的结果如图所示。

如果想修改列与列之间的分隔符,可以传入 delimiter 参数,其代码如下:

代码语言:javascript
复制
  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 参数为空格,此时输出结果的每一列就是以空格分隔了,内容如下:

代码语言:javascript
复制
  id name age
  10001 Mike 20
  10002 Bob 22
  10003 Jordan 21

另外,我们也可以调用 writerows() 方法写入多行,此时参数就需要为二维列表,例如:

代码语言:javascript
复制
  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]])

输出效果是相同的,内容如下:

代码语言:javascript
复制
  id,name,age
  10001,Mike,20
  10002,Bob,22
  10003,Jordan,21

但是一般情况下,爬虫爬取的都是结构化数据,我们一般会用字典来表示。在 csv 库中也提供了字典的写入方式,示例如下:

代码语言:javascript
复制
  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() 方法传入相应字典即可。最终写入的结果是完全相同的,内容如下:

代码语言:javascript
复制
  id,name,age
  10001,Mike,20
  10002,Bob,22
  10003,Jordan,21

这样就可以完成字典到 csv 文件的写入了。

另外,如果想追加写入的话,可以修改文件的打开模式,即将 open() 函数的第二个参数改成 a ,代码如下:

代码语言:javascript
复制
  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})

这样在上面的基础上再执行这段代码,文件内容便会变成:

代码语言:javascript
复制
  id,name,age
  10001,Mike,20
  10002,Bob,22
  10003,Jordan,21
  10004,Durant,22

可见,数据被追加写到文件中。

如果要写入中文内容的话,可能会遇到字符编码的问题,此时需要给 open 参数指定编码格式。比如,这里再写入一行包含中文的数据,代码需要改写如下:

代码语言:javascript
复制
  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 文件。例如,将刚才写入的文件内容读出来,相关代码如下:

代码语言:javascript
复制
  import csv
  with open('data.csv', 'r', encoding='utf-8')as csvfile:
      reader = csv.reader(csvfile)
      for row in reader:
          print(row)

运行结果如下:

代码语言:javascript
复制
  ['id', 'name', 'age']
  ['10001', 'Mike', '20']
  ['10002', 'Bob', '22']
  ['10003', 'Jordan', '21']
  ['10004', 'Durant', '22']
  ['10005', '王伟', '22']

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

另外,如果接触过 pandas 的话,可以利用 read_csv() 方法将数据从 CSV 中读取出来,例如:

代码语言:javascript
复制
  import pandas as pd
  df = pd.read_csv('data.csv')
  print(df)

运行结果如下:

我们可以发现中文没有对齐,感觉有点怪怪的~!我们首先需要知道为什么没有对齐。它之所以没有对齐,是因为它以最长的字符串为标准进行右对齐的,同时又因为汉字是宽字符(占用两个字符的位置),它现在还是以为中文汉字只有占一个字符位。如何解决这个问题呢?其实很简单,设置属性 display.unicode.ambiguous_as_wide 和 display.unicode.east_asian_width ,将这两个属性都设置为 True 即可,代码如下:

代码语言:javascript
复制
  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 文件的写入和读取方式。这也是一种常用的数据存储方式,需要熟练掌握。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-24,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写入
  • 读取
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com