- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
14.2 项目:从 CSV 文件中删除表头
假设你有一个枯燥的任务,要删除几百CSV文件的第一行。也许你会将它们送入一个自动化的过程,只需要数据,不需要每列顶部的表头。可以在Excel中打开每个文件,删除第一行,并重新保存该文件,但这需要几个小时。让我们写一个程序来做这件事。
该程序需要打开当前工作目录中所有扩展名为.csv的文件,读取CSV文件的内容,并除掉第一行的内容重新写入同名的文件。这将用新的、无表头的内容替换CSV文件的旧内容。
警告
与往常一样,当你写程序修改文件时,一定要先备份这些文件,以防万一你的程序没有按期望的方式工作。你不希望意外地删除原始文件。
总的来说,该程序必须做到以下几点:
· 找出当前工作目录中的所有CSV文件。
· 读取每个文件的全部内容。
· 跳过第一行,将内容写入一个新的CSV文件。
在代码层面上,这意味着该程序需要做到以下几点:
· 循环遍历从os.listdir()得到的文件列表,跳过非CSV文件。
· 创建一个CSV Reader对象,读取该文件的内容,利用line_num属性确定要跳过哪一行。
· 创建一个CSV Writer对象,将读入的数据写入新文件。
针对这个项目,打开一个新的文件编辑器窗口,并保存为removeCsvHeader.py。
第1步:循环遍历每个CSV文件
程序需要做的第一件事情,就是循环遍历当前工作目录中所有CSV文件名的列表。让removeCsvHeader.py看起来像这样:
#! python3 # removeCsvHeader.py - Removes the header from all CSV files in the current # working directory. import csv, os os.makedirs('headerRemoved', exist_ok=True) # Loop through every file in the current working directory. for csvFilename in os.listdir('.'): if not csvFilename.endswith('.csv'): ❶ continue # skip non-csv files print('Removing header from ' + csvFilename + '...') # TODO: Read the CSV file in (skipping first row). # TODO: Write out the CSV file.
os.makedirs()调用将创建headerRemoved文件夹,所有的无表头的CSV文件将写入该文件夹。针对os.listdir('.')进行for循环完成了一部分任务,但这会遍历工作目录中的所有文件,所以需要在循环开始处添加一些代码,跳过扩展名不是.csv的文件。如果遇到非CSV文件,continue语句❶让循环转向下一个文件名。
为了让程序运行时有一些输出,打印出一条消息说明程序在处理哪个CSV文件。然后,添加一些TODO注释,说明程序的其余部分应该做什么。
第2步:读入CSV文件
该程序不会从原来的CSV文件删除第一行。但是,它会创建新的CSV文件副本,不包含第一行。因为副本的文件名与原来的文件名一样,所以副本会覆盖原来的文件。
该程序需要一种方法,来知道它的循环当前是否在处理第一行。为removeCsvHeader.py添加以下代码。
#! python3 # removeCsvHeader.py - Removes the header from all CSV files in the current # working directory. --snip-- # Read the CSV file in (skipping first row). csvRows = [] csvFileObj = open(csvFilename) readerObj = csv.reader(csvFileObj) for row in readerObj: if readerObj.line_num == 1: continue # skip first row csvRows.append(row) csvFileObj.close() # TODO: Write out the CSV file.
Reader对象的line_num属性可以用来确定当前读入的是CSV文件的哪一行。另一个for循环会遍历CSV Reader对象返回所有行,除了第一行,所有行都会添加到csvRows。
在for循环遍历每一行时,代码检查reader.line_num是否设为1。如果是这样,它执行continue,转向下一行,不将它添加到csvRows中。对于之后的每一行,条件永远是False,该行将添加到csvRows中。
第3步:写入CSV文件,没有第一行
现在csvRows包含了除第一行的所有行,该列表需要写入headerRemoved文件夹中的一个CSV文件。将以下代码添加到removeCsvHeader.py:
#! python3 # removeCsvHeader.py - Removes the header from all CSV files in the current # working directory. --snip-- # Loop through every file in the current working directory. ❶ for csvFilename in os.listdir('.'): if not csvFilename.endswith('.csv'): continue # skip non-CSV files --snip-- # Write out the CSV file. csvFileObj = open(os.path.join('headerRemoved', csvFilename), 'w', newline='') csvWriter = csv.writer(csvFileObj) for row in csvRows: csvWriter.writerow(row) csvFileObj.close()
CSV Writer对象利用csvFilename(这也是我们在CSV Reader中使用的文件名),将列表写入headerRemoved中的一个CSV文件。这将覆盖原来的文件。
创建Writer对象后,我们循环遍历存储在csvRows中的子列表,将每个子列表写入该文件。
这段代码执行后,外层for循环❶将循环到os.listdir('.')中的下一个文件名。循环结束时,程序就结束了。
为了测试你的程序,从http://nostarch.com/automatestuff/下载removeCsvHeader.zip,将它解压缩到一个文件夹。在该文件夹中运行removeCsvHeader.py程序。输出将是这样的:
Removing header from NAICS_data_1048.csv... Removing header from NAICS_data_1218.csv... --snip-- Removing header from NAICS_data_9834.csv... Removing header from NAICS_data_9986.csv...
这个程序应该在每次从CSV文件中删除第一行时,打印一个文件名。
第4步:类似程序的想法
针对CSV文件写的程序类似于针对Excel文件写的程序,因为它们都是电子表格文件。你可以编程完成以下任务:
· 在一个CSV文件的不同行,或多个CSV文件之间比较数据。
· 从CSV文件拷贝特定的数据到Excel文件,或反过来。
· 检查CSV文件中无效的数据或格式错误,并向用户提醒这些错误。
· 从CSV文件读取数据,作为Python程序的输入。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论