返回介绍

8.2 数据存储

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

我们已经讲过几种数据存储的方法,现在有了可用的数据,我们先来复习一下这些方法。如果你正在使用数据库、知道预期的表格格式,并想要保存已经清洗过的数据,那么你应该继续使用第 6 章讲过的 Python 库来连接数据库并保存数据。对于这些 Python 库中的大部分库,你都可以使用游标直接向数据库提交。

 我们强烈建议在数据库脚本中添加错误信息,在遇到网络故障或数据库故障时可以捕获这些错误信息。我们建议频繁向数据库提交,这样可以避免网络问题或延迟问题影响脚本的运行。

如果你用的是第 6 章中讲过的 SQLite 例子,你需要将新的干净数据保存到你的数据库中。我们来看一下如何做到这一点:

  import dataset

  db = dataset.connect('sqlite:///data_wrangling.db') ➊

  table = db['unicef_survey'] ➋

  for row_num, data in enumerate(zipped_data): ➌
    for question, answer in data: ➍
      data_dict = { ➎
        'question': question[1], ➏
        'question_code': question[0],
        'answer': answer,
        'response_number': row_num, ➐
      'survey': 'mn',
    }

  table.insert(data_dict) ➑

❶ 这里我们访问本地数据库。如果你将文件保存到其他目录,一定要修改文件路径,将其修改为数据库文件相对于当前目录的位置(例如,如果数据库文件保存在上层目录中:file:///../datawrangling.db)。

❷ 本行代码创建一个新表:unicef_data。我们知道很多 UNICEF 调查都有相同的规律,所以我们这个数据库名是没有歧义、可复用的。

❸ 我们希望保存所在的行编号,这样每个回答都有一个编号。本行代码用到了 enumerate 函数,这样在数据库中可以找到(每一行 / 每一个回答的)每一条数据(它们的共用一个行编号)。

❹ 我们知道,我们的数据被分割成元组,标题列表是元组的第一个元素,问题回答是元组的第二个元素。本行代码利用 for 循环解析其中包含的数据并进行存储。

❺ 每一个问题和回答在数据库中都有对应的条目,所以我们可以将每行(即每次采访)所有的回答合并在一起。本行代码创建一个字典,其中包含每次采访中每个回答的必要数据。

❻ 标题列表中第二个元素是问题的详细说明。本行代码将其保存为 question,并将 UNICEF 问题代码保存为 question_code。

❼ 为了记录每一行回答(或每一次采访),本行代码添加了 enumerate 函数得到的 rownum。

❽ 最后,利用新表的 insert 方法将新字典插入我们的数据库中。

我们希望将清洗过的数据保存到 SQLite 数据库中。我们创建了一个新的数据库,用到了 enumerate 函数,这样我们可以合并每一个回答(每一行)。如果我们要访问数据,可以访问新表,利用第 6 章学过的函数来查看所有的数据记录,并在需要时进行检索。

如果你希望将清洗过的数据导出到简单文件中,应该也很容易做到。我们来看一下:

from csv import writer


def write_file(zipped_data, file_name):
  with open(file_name, 'wb') as new_csv_file: ➊
    wrtr = writer(new_csv_file) ➋
    titles = [row[0][1] for row in zipped_data[0]] ➌
    wrtr.writerow(titles) ➍
    for row in zipped_data:
      answers = [resp[1] for resp in row] ➎
      wrtr.writerow(answers)


write_file(zipped_data, 'cleaned_unicef_data.csv') ➏

❶ with...as 的作用是将第一个函数的输出赋值给第二个变量名。本行代码将新文件 open(file_name, 'wb') 赋值给变量 new_csv_file。'wb' 的意思是以二进制模式写入。

❷ 初始化 CSV writer 对象,传入一个打开的文件,然后将 writer 对象赋值给 wrtr 变量。

❸ writer 对象需要数据列表来逐行写入,本行创建的是标题行的标题列表。长标题是元组第一部分的第二个元素,所以对应的代码是 row[0][1]。

❹ 用到了 writer 对象的 writerow 方法,将一个可迭代对象转换成一行逗号分隔的数据。本行代码写入的是标题行。

❺ 利用列表生成式提取出所有回答(元组的第二个元素)。

❻ 将利用列表生成式创建的所有列表或回答写入 CSV 数据文件。

这里我们用到了学过的语法,也用到了一些新语法。我们已经学过如何用 with...as 将简单函数的返回值赋值给一个变量名。这里我们希望将打开的文件赋值给 new_csv_file 变量。这种语法通常用于文件和其他 I/O 对象,因为 Python 执行完 with 代码块中的代码之后,它会自动关闭文件,这很棒!

此外,代码中我们用到了 CSV writer 对象,与 CSV reader 对象的用法类似。writerow 可以将包含所有数据列的列表写入到 CSV 文件中。

 writerow 方法接受一个可迭代对象,所以一定要传入一个列表或元组。如果你传入一个字符串,那么看到一些有趣的 CSV(“l,i,k,e,,t,h,i,s”)时不要惊讶。

我们还用到了列表生成式来创建标题列表和回答列表。由于我们不需要用这个函数生成一个新对象或修改过的对象,所以没有返回任何值。这个函数可以帮我们复习目前学过的许多概念。

如果你想用其他方法来保存数据,可以参考第 6 章给出的关于保存数据的建议。保存完清洗过的数据之后,你可以继续进行后面的清洗过程,并对数据进行分析。

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

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

发布评论

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