假设有一个枯燥的任务,要删除几百CSV文件的第一行。 也许会将它们送入一个自动化的过程,只需要数据, 不需要每列顶部的表头。可以在Excel中打开每个文件, 删除第一行,并重新保存该文件,但这需要几个小时。 接下来写一个程序来做这件事。
该程序需要打开当前工作目录中所有扩展名为.csv的文件, 读取CSV文件的内容,并除掉第一行的内容重新写入同名的文件。 这将用新的、无表头的内容替换CSV文件的旧内容。
警告: 与往常一样,当写程序修改文件时,一定要先备份这些文件, 以防万一程序没有按期望的方式工作。不希望意外地删除原始文件。
总的来说,该程序必须做到以下几点:
- 找出当前工作目录中的所有CSV文件。
- 读取每个文件的全部内容。
- 跳过第一行,将内容写入一个新的CSV文件。
在代码层面上,这意味着该程序需要做到以下几点:
- 循环遍历从
os.listdir()得到的文件列表,跳过非CSV文件。 - 创建一个
CSV Reader对象,读取该文件的内容,利用line_num属性确定要跳过哪一行。 - 创建一个
CSV Writer对象,将读入的数据写入新文件。
针对这个项目,打开一个新的文件编辑器窗口,并保存为removeCsvHeader.py 。
removeCsvHeader.py - 移除当前工作目录下所有CSV文件的标题行。
#! python3
import csv, os
os.makedirs('xx_headerRemoved', exist_ok=True)
遍历当前工作目录中的每个文件。
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.
Removing header from xx_10M.csv... Removing header from xx_example.csv... Removing header from xx_output.csv... Removing header from xx_to.csv...
os.makedirs() 调用将创建 headerRemoved 文件夹,
所有的无表头的CSV文件将写入该文件夹。
针对 os.listdir('.')进行 for 循环完成了一部分任务,
但这会遍历工作目录中的所有文件,所以需要在循环开始处添加一些代码,
跳过扩展名不是 xsv 的文件。
如果遇到非 CSV 文件, continue 语句让循环转向下一个文件名。
为了让程序运行时有一些输出,打印出一条消息说明程序在处理哪个CSV文件。
然后,添加一些 TODO 注释,
说明程序的其余部分应该做什么。
#! 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 中。
写入CSV文件
写入CSV文件,没有第一行。
现在csvRows 包含了除第一行的所有行,
该列表需要写入headerRemoved 文件夹中的一个CSV文件。
将以下代码添加到 removeCsvHeader.py :
removeCsvHeader.py - 删除当前工作目录下所有CSV文件的表头行。
#! python3
import csv, os
os.makedirs('xx_headerRemoved', exist_ok=True)
遍历当前工作目录中的每个文件。
for csvFilename in os.listdir('.'):
if not csvFilename.endswith('.csv'):
continue # skip non-csv files
print('Removing header from ' + csvFilename + '...')
# 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()
# Write out the CSV file.
csvFileObj = open(os.path.join('xx_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 程序。
这个程序应该在每次从 CSV 文件中删除第一行时,
打印一个文件名。