返回介绍

3.1 CSV 数据

发布于 2024-01-27 21:43:11 字数 11081 浏览 0 评论 0 收藏 0

我们要学习的第一个机器可读的文件格式是 CSV。CSV 文件(简称为 CSV)是指将数据列用逗号分隔的文件。文件的扩展名是 .csv。

另一种数据类型,叫作制表符分隔值(tab-separated values,TSV)数据,有时也与 CSV 归为一类。TSV 与 CSV 唯一的不同之处在于,数据列之间的分隔符是制表符(tab),而不是逗号。文件的扩展名通常是 .tsv,但有时也用 .csv 作为扩展名。从本质上来看,.tsv 文件与 .csv 文件在 Python 中的作用是相同的。

 如果文件的扩展名是 .tsv,那么里面包含的很可能是 TSV 数据。如果文件的扩展名是 .csv,那么里面包含的可能是 CSV 数据,但也可能是 TSV 数据。一定要打开文件查看一下,这样你可以在导入数据之前就明确所处理的数据类型。

对于本章的 CSV 实例,我们采用的是来自世界卫生组织(WHO)的数据。WHO 拥有许多大型数据集(http://apps.who.int/gho/data/node.main),并且提供多种格式的数据。本例选择的数据集包含全球各国的预期寿命。访问网页(http://apps.who.int/gho/data/node.main.3?lang=en)查看预期寿命数据,你会发现这个数据集有几个不同的版本。本例中使用的是 CSV(纯文本,下载地址:http://apps.who.int/gho/athena/data/data-text.csv?target=GHO/WHOSIS_000002,WHOSIS_000001,WHOSIS_000015&profile=text&filter=COUNTRY:*;REGION:AFR;REGION:AMR;REGION:SEAR;REGION:EUR;REGION:EMR;REGION:WPR;SEX:*)。

用文本编辑器 1 打开这个 CSV 文件,你会看到类似表 3-1 的许多行数据。

1为了完成本章练习,你需要一个好用的文本编辑器。如果还没有安装的话,你可以按 1.2.5 节的说明来安装。

表3-1:两个样本数据记录a

CSV标题

样本记录1

样本记录2

指标

60 岁时预期寿命(年)

出生时预期寿命(年)

发布状态

已发布

已发布

年份

1990

1990

WHO 地区

欧洲

美洲

世界银行收入分组

高收入

中低收入

国家

捷克共和国

伯利兹

性别

女性

男女合计

示值

19

71

数值大小

19.00000

71.00000

最低值

最高值

备注

a 加粗项包含在下文的样本数据中。

为了让数据更容易阅读,下面给出一个数据样本,其中只包含经过挑选的特定字段(表 3-1 中的加粗项)。在文本编辑器中打开 CSV 文件,你看到的数据应该与其类似:

"Year","Country","Sex","Display Value","Numeric"
"1990","Andorra","Both sexes","77","77.00000"
"2000","Andorra","Both sexes","80","80.00000"
"2012","Andorra","Female","28","28.00000"
"2000","Andorra","Both sexes","23","23.00000"
"2012","United Arab Emirates","Female","78","78.00000"
"2000","Antigua and Barbuda","Male","72","72.00000"
"1990","Antigua and Barbuda","Male","17","17.00000"
"2012","Antigua and Barbuda","Both sexes","22","22.00000"
"2012","Australia","Male","81","81.00000"

预览 CSV 文件的另一种方法是用电子表格程序打开,比如 Excel 或 Google Spreadsheets。这些程序将每一个数据条目显示为单独的一行。

3.1.1 如何导入CSV数据

前面我们学习了一点关于数据的知识,下面用 Python 打开这个文件,并将数据转换成 Python 可以理解的格式。这只要几行代码:

import csv

csvfile = open('data-text.csv', 'rb')
reader = csv.reader(csvfile)

for row in reader:
  print row

我们来一行一行地阅读上面的代码。在上一章里,我们所有的代码都是在 Python 解释器中输入的,但随着代码变得越来越长、越来越复杂,在文件中编写代码并运行要方便一些。读完这段代码,我们将把它保存在一个 .py 文件中(.py 文件是一个 Python 文件),然后在命令行中运行这个文件。

脚本的第一行代码导入了一个叫作 csv 的库:

import csv

Python 是一个代码包,提供了你可以在 Python 程序中使用的功能。这里导入的 csv 库是 Python 标准库(或 stdlib)的一部分,随 Python 一起安装。将库导入到文件中后,我们就可以使用这个库。如果没有这个库的话,脚本将会变得很长——csv 库提供了辅助函数,这样一来,为了完成更复杂的任务,我们就不必写这么多的代码。

第二行代码将 data-text.csv 文件传入 open 函数,这个文件应该和脚本位于同一文件夹下:

csvfile = open('data-text.csv', 'rb')

 函数(function)是一段代码,在被调用时执行相应的任务。它和我们在第 2 章学过的 Python 数据类型的方法十分相似。函数有时会接收一个(或多个)输入。这些输入叫作参数(argument)。函数的功能是基于参数的。函数有时也会返回一个输出,可以被保存或使用。

open 是 Python 的内置函数(这里列出了 Python 所有的内置函数:https://docs.python.org/2/library/functions.html),也就是说,打开文件的行为是如此常见,所以 Python 核心贡献者认为应把这个行为添加到 Python 的默认安装里。在使用 open 函数时,我们传入一个文件名作为第一个参数(这里用的是 'data-text.csv'),然后选择指定文件打开的模式(我们用的是 'rb')。如果查看 open 函数的文档(https://docs.python.org/2/library/functions.html#open),你会发现,'rb' 参数的意思是我们以只读方式二进制方式打开文件。以二进制方式打开文件,可以让代码在 Windows 上和基于 Unix 的操作系统上都能运行。另一种常见的模式是写入('w' 或 'wb',后者表示以二进制方式写入)。

 如果你想读取文件,以只读方式打开文件。如果你想写入文件,以写入方式打开文件。

我们将这个函数的输出保存在变量 csvfile 中。现在 csvfile 保存一个打开的文件作为它的值。

在下一行代码中,我们将 csvfile 传递给 csv 模块的 reader 函数。这个函数的作用是让 csv 模块将打开的文件当作 CSV 来读取:

reader = csv.reader(csvfile)

函数 csv.reader(csvfile) 的输出保存在变量 reader 中。现在 reader 变量保存的是已打开文件的 Python CSV reader。有了这个 CSV reader,我们用简单的 Python 命令就可以轻松查看文件中的数据。最后一段代码中,我们使用了所谓的 for 循环。

for 循环是一种遍历 Python 对象的方法,通常与列表一起使用。for 循环告诉 Python 代码:“对于这个列表中的每一个元素,做点什么。”在一个 for 循环中,for 后面的第一个单词是用来保存列表(或其他可迭代对象)中每一个对象的变量。for 循环下面的代码利用这个变量对该元素执行更多的操作或计算。因此,最好用有意义的单词做变量名,这样你和其他人都能轻松阅读并理解代码。

 还记得第 2 章里出现过的“无效的标记”(invalid token)吗? for 是 Python 里另一个特殊的标记(token),只能用来创建 for 循环。标记可以将我们在解释器或脚本中输入的内容翻译成计算机能够执行的命令。

试着在 Python 解释器中运行下面的代码:

dogs = ['Joker', 'Simon', 'Ellie', 'Lishka', 'Fido']
for dog in dogs:
  print dog

利用这个 for 循环,我们将每一只狗狗的名字都保存在 for 循环的 dog 变量中。对于 for 循环的每一次迭代,我们打印出狗狗的名字(保存在变量 dog 中)。当程序遍历完每一只狗狗的名字(或列表中的每一个元素)后,代码停止运行。

在 IPython 中退出缩进代码块

在 IPython 终端里编写 for 循环或其他缩进代码块时,一定要检查一下,确保提示符从缩进代码块的样式 ... 变成了一个新的 In 提示符。最简单的方法就是,在完成最后一行缩进代码后敲下 Return 键。你应该看到一个新的 In 提示符,然后再输入循环之外的代码:

In [1]: dogs = ['Joker', 'Simon', 'Ellie', 'Lishka', 'Fido']
    
In [2]: for dog in dogs:
   ...:   print dog   ➊
   ...:         ➋
Joker
Simon
Ellie
Lishka
Fido
    
In [3]:         ➌

➊ IPython 的自动缩进提示符(...: 后面跟着四个空格)。

➋ 在空行按下 Return 键,退出缩进代码块并运行代码。

➌ IPython 的代码运行结束后,出现了新的提示符。

在我们用来读取 CSV 的代码中,reader 对象是一个保存数据行的 Python 容器。在 reader 的 for 循环中,我们将每一行数据保存在变量 row 中。下一行代码的意思是,我们让 Python 打印出每一行数据:

for row in reader:
  print row

现在我们已经能够导入数据并对数据进行遍历,下面开始对数据进行真正的探索。

3.1.2 将代码保存到文件中并在命令行中运行

作为开发者,在写代码时,即使是中间过程的部分代码片段,你也会希望保存下来,以便后续检查和使用。保持代码结构清晰,并及时保存代码,即使中途被打断,你也可以从上次中断的地方顺畅地继续工作。

我们将到目前为止所有的代码保存到文件中并运行。代码应该是这样的(如果你还没有完成这一步的话,打开文本编辑器,创建一个新文件,将这段代码输入进去):

import csv

csvfile = open('data-text.csv', 'rb')
reader = csv.reader(csvfile)

for row in reader:
  print row

 注意大小写、间距和换行。如果各行的代码间距各不相同或者大小写错误的话,代码是无法正常运行的。一定要严格按上面的代码输入,利用四个空格来缩进。这一点很重要,因为 Python 区分大小写,并利用缩进来表示代码的结构。

用文本编辑器将代码保存为 .py(Python)文件。完整的文件名应该是像这样的:import_csv_data.py。

将数据文件 data-text.csv 放到你刚刚保存 Python 文件的同一个文件夹内。如果你想把文件放到其他位置,需要对文件位置对应的代码做适当修改。

打开不同位置的文件

在目前的代码中,我们将文件路径传入 open 函数,像这样:

open('data-text.csv', 'rb')

但如果数据文件位于一个叫作 data 的子文件夹,我们需要修改脚本,让它去那里寻找数据文件。修改后的代码如下:

open('data/data-text.csv', 'rb')

在上面的例子中,我们的文件结构是像这样的:

data_wrangling/
`-- code/
   |-- import_csv_data.py
   `-- data/
      `-- data-text.csv

如果你找不到自己的文件,可以在 Mac 或 Linux 计算机上打开命令行,使用下列命令来浏览文件夹。

· ls 返回文件的列表。

· pwd 给出当前位置。

· cd ../ 进入上层文件夹。

· cd ../../ 向上移动两层目录。

· cd data 进入 data 文件夹,该文件夹位于当前文件夹下(可以用 ls 来查看)。

查阅附录 C 可以了解用命令行在文件夹之间跳转的更多内容,其中还包括针对 Windows 用户的整整一节内容。

保存好文件后,你可以用命令行来运行它。打开命令行(终端或 cmd),跳转到文件所在的位置。假设你把文件放在~/Projects/data_wrangling/code 中。想要在 Mac 命令行中跳转到那里,你可以使用变更目录或文件夹命令(cd):

cd ~/Projects/data_wrangling/code

跳转到正确的位置后,你就可以运行 Python 文件。到目前为止,我们都是在 Python 解释器中运行代码。我们将文件保存为 import_csv_data.py。想要在命令行中运行 Python 文件,你只需要输入 python,敲空格,然后输入文件名即可。我们来试一下运行 Python 文件:

python import_csv_data.py

你得到的输出看起来应该像一串列表——和下面给出的数据类似,但数据量要大得多。

['Healthy life expectancy (HALE) at birth (years)', 'Published', '2012',
 'Western Pacific', 'Lower-middle-income', 'Samoa', 'Female', '66',
 '66.00000', '', '', '']
['Healthy life expectancy (HALE) at birth (years)', 'Published', '2012',
 'Eastern Mediterranean', 'Low-income', 'Yemen', 'Both sexes', '54',
 '54.00000', '', '', '']
['Healthy life expectancy (HALE) at birth (years)', 'Published', '2000',
 'Africa', 'Upper-middle-income', 'South Africa', 'Male', '49', '49.00000',
 '', '', '']
['Healthy life expectancy (HALE) at birth (years)', 'Published', '2000',
 'Africa', 'Low-income', 'Zambia', 'Both sexes', '36', '36.00000', '', '', '']
['Healthy life expectancy (HALE) at birth (years)', 'Published', '2012',
 'Africa', 'Low-income', 'Zimbabwe', 'Female', '51', '51.00000', '', '', '']

你得到上面的输出了吗?如果没有的话,花一分钟的时间阅读你得到的错误信息。从中发现出错的地方可能在哪里了吗?花点时间去搜索错误的原因,看看其他人解决相同的错误都用了哪些方法。关于如何解决错误,如果你需要额外的帮助,可查阅附录 E。

 从现在开始,我们将会在代码编辑器里编写大多数代码,保存文件,然后在命令行中运行。Python 解释器仍然是一个有用的工具,可以用来测试代码片段,但随着代码变得越来越长、越来越复杂,在代码提示符中维护代码将越来越困难。

无论是我们正在写的代码,还是我们将面对的许多其他问题,解决问题的方法往往不止一种。csv.reader() 返回的是一个数据的列表,里面包含的是文件中的每一行数据,在我们刚开始处理问题时,这是一个很容易理解的方法。下面要对脚本做少许修改,将列表行改成字典行。这样在我们探索数据集的过程中,读取数据、对比数据和理解数据会变得更加容易。

在文本编辑器中,将第 4 行 reader = csv.reader(csvfile) 修改成 reader = csv.DictReader(csvfile)。现在你的代码应该是这样的:

import csv

csvfile = open('data-text.csv', 'rb')
reader = csv.DictReader(csvfile)

for row in reader:
  print row

保存文件并重新运行,每一个数据记录变成一个字典。字典的键来自于 CSV 文件的第一行。后面所有行都是字典的值。下面是一行数据对应的输出:

{
  'Indicator': 'Healthy life expectancy (HALE) at birth (years)',
  'Country': 'Zimbabwe',
  'Comments': '',
  'Display Value': '49',
  'World Bank income group': 'Low-income',
  'Numeric': '49.00000',
  'Sex': 'Female',
  'High': '',
  'Low': '',
  'Year': '2012',
  'WHO region': 'Africa',
  'PUBLISH STATES': 'Published'
}

现在我们已经成功地将 CSV 数据导入到 Python 中,也就是说,我们能够从文件中获取数据,并将其转换成 Python 可用的格式(字典),for 循环可以让我们直观地查看数据。我们可以利用 csv 库两种不同的 reader 来查看数据,一种是列表形式,一种是字典形式。在开始探索和分析数据集时,我们会再次用到这个库。下面继续学习导入 JSON 数据。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文