说说如何利用 Python 处理 CSV 文件

CSV 表示 “Comma-Separated Values (逗号分隔的值) ” , CSV 文件是简化的电子表格,实际为纯文本文件。

一个 CSV 文件,格式是这样的:

因为 CSV 文件中的每个单元格都是以逗号分割,所以也许有人会对每行文本调用 split() 方法,来解析 CSV 文件。但 CSV 文件也有自己的转义字符,通过转义字符,允许逗号和其他字符作为值的一部分,但单纯使用 split() 方法不能处理这些转义字符。因为这些潜在的缺陷,所以建议总是使用 csv 模块来读写 CSV 文件。

csv 模块是 Python 自带的,所以可以直接导入。

1 Reader 对象

要使用 csv 模块从 CSV 文件中读取数据,我们需要创建一个 Reader 对象。 通过 Reader 对象,我们可以迭代遍历 CSV 文件中的每一行内容。

import os

import csv
import logging

# logging.disable(logging.CRITICAL)
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s - %(message)s')
'''
读取 CSV
@author Deniro Li
'''
os.chdir('F:/temp')

file = open('CsvDataSource.csv')
reader = csv.reader(file)
data = list(reader)
logging.info('data -> %s', str(data))

运行结果:

INFO - data -> [['Dallas', '47', 'Janet Fuller', '445 Upland Pl.', 'Trial', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Lyon', '38', 'Andrew Heiniger', '347 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Dallas', '43', 'Susanne Smith', '2 Upland Pl.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Berne', '22', 'Bill Ott', '250 - 20th Ave.', 'Active', ' "47.21"', ' "8.31"', ' "1996-07-22 00:00:00"'], ['Boston', '32', 'Michael Ott', '339 College Av.', 'Trial', ' "42.21"', ' "-71.5"', ' "1996-07-22 00:00:00"'], ['Dallas', '4', 'Sylvia Ringer', '365 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Boston', '23', 'Julia Heiniger', '358 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Chicago', '39', 'Mary Karsen', '202 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Dallas', '40', 'Susanne Miller', '440 - 20th Ave.', 'Trial', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Berne', '9', 'James Schneider', '277 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Dallas', '36', 'John Steel', '276 Upland Pl.', 'Suspended', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Chicago', '35', 'George Karsen', '412 College Av.', 'Suspended', ' "41.50"', ' "-87.37"', ' "1996-07-22 00:00:00"'], ['Dallas', '37', 'Michael Clancy', '19 Seventh Av.', 'Deleted', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Lyon', '2', 'Anne Miller', '20 Upland Pl.', 'Active', ' ""', ' "" ', ' "1996-07-22 00:00:00"'], ['Dallas', '0', 'Laura Steel', '429 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Lyon', '28', 'Susanne White', '74 - 20th Ave.', 'Deleted', ' ""', ' "" ', ' "1996-07-22 00:00:00"'], ['Paris', '5', 'Laura Miller', '294 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Lyon', '17', 'Laura Ott', '443 Seventh Av.', 'Active', ' "45.45"', ' "4.50" ', ' "1996-07-22 00:00:00"'], ['New York', '46', 'Andrew May', '172 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['New York', '44', 'Sylvia Ott', '361 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Dallas', '19', 'Susanne Heiniger', '86 - 20th Ave.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Chicago', '11', 'Julia White', '412 Upland Pl.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Dallas', '10', 'Anne Fuller', '135 Upland Pl.', 'Active', ' "32.46"', ' "-96.46"', ' "1996-07-22 00:00:00"'], ['New York', '41', 'Bill King', '546 College Av.', 'Deleted', ' "40.47"', ' "-73.58"', ' "1996-07-22 00:00:00"'], ['Oslo', '45', 'Janet May', '396 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Paris', '18', 'Sylvia Fuller', '158 - 20th Ave.', 'Trial', ' "48.48"', ' "2.20"', ' "1996-07-22 00:00:00"'], ['San Francisco', '48', 'Robert White', '549 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['Paris', '25', 'Sylvia Steel', '269 College Av.', 'Suspended', ' ""', ' ""', ' "1996-07-22 00:00:00"'], ['San Francisco', '7', 'James Peterson', '231 Upland Pl.', 'Active', ' "37.47"', ' "-122.26"', ' "1996-12-12 00:00:00"'], ['Oslo', '42', 'Robert Ott', '503 Seventh Av.', 'Trial', ' "59.57"', ' "10.42"', ' "1996-09-09 00:00:00"']]

要用 csv 模块读取 CSV 文件,首先先使用 open() 函数打开它 ,就像打开任何其他文本文件一样。然后将它传递给 csv .reader() 函数。 这个函数将返回一个 Reader 对象。注意,csv .reader() 函数不接受文件名作为入参。

要访问 Reader 对象中的值,最直接的方法,就是利用 list() 将它转换成一个普通 Python 列表。它实际为一个包含列表的列表,用于表示二维数据。

我们还可以使用表达式 data [ row ][ col ] 来访问 CSV 中特定行和列的值。其中, row 是 data 中一个列表的下标, col 是该列表中,我们想访问的项的下标:

logging.info('data[0][0] -> %s', str(data[0][0]))
logging.info('data[2][3] -> %s', str(data[2][3]))
logging.info('data[5][2] -> %s', str(data[5][2]))

运行结果:

INFO - data[0][0] -> Dallas
INFO - data[2][3] -> 2 Upland Pl.
INFO - data[5][2] -> Sylvia Ringer

2 逐行读取

file = open('CsvDataSource.csv')
reader = csv.reader(file)
logging.debug('reader -> '+str(reader))
for row in reader:
    logging.info('Row #%d->  %s',reader.line_num, str(row))

运行结果:

DEBUG - reader -> <_csv.reader object at 0x0000000002716A08>
INFO - Row #1->  ['Dallas', '47', 'Janet Fuller', '445 Upland Pl.', 'Trial', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #2->  ['Lyon', '38', 'Andrew Heiniger', '347 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #3->  ['Dallas', '43', 'Susanne Smith', '2 Upland Pl.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #4->  ['Berne', '22', 'Bill Ott', '250 - 20th Ave.', 'Active', ' "47.21"', ' "8.31"', ' "1996-07-22 00:00:00"']
INFO - Row #5->  ['Boston', '32', 'Michael Ott', '339 College Av.', 'Trial', ' "42.21"', ' "-71.5"', ' "1996-07-22 00:00:00"']
INFO - Row #6->  ['Dallas', '4', 'Sylvia Ringer', '365 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #7->  ['Boston', '23', 'Julia Heiniger', '358 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #8->  ['Chicago', '39', 'Mary Karsen', '202 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #9->  ['Dallas', '40', 'Susanne Miller', '440 - 20th Ave.', 'Trial', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #10->  ['Berne', '9', 'James Schneider', '277 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #11->  ['Dallas', '36', 'John Steel', '276 Upland Pl.', 'Suspended', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #12->  ['Chicago', '35', 'George Karsen', '412 College Av.', 'Suspended', ' "41.50"', ' "-87.37"', ' "1996-07-22 00:00:00"']
INFO - Row #13->  ['Dallas', '37', 'Michael Clancy', '19 Seventh Av.', 'Deleted', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #14->  ['Lyon', '2', 'Anne Miller', '20 Upland Pl.', 'Active', ' ""', ' "" ', ' "1996-07-22 00:00:00"']
INFO - Row #15->  ['Dallas', '0', 'Laura Steel', '429 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #16->  ['Lyon', '28', 'Susanne White', '74 - 20th Ave.', 'Deleted', ' ""', ' "" ', ' "1996-07-22 00:00:00"']
INFO - Row #17->  ['Paris', '5', 'Laura Miller', '294 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #18->  ['Lyon', '17', 'Laura Ott', '443 Seventh Av.', 'Active', ' "45.45"', ' "4.50" ', ' "1996-07-22 00:00:00"']
INFO - Row #19->  ['New York', '46', 'Andrew May', '172 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #20->  ['New York', '44', 'Sylvia Ott', '361 College Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #21->  ['Dallas', '19', 'Susanne Heiniger', '86 - 20th Ave.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #22->  ['Chicago', '11', 'Julia White', '412 Upland Pl.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #23->  ['Dallas', '10', 'Anne Fuller', '135 Upland Pl.', 'Active', ' "32.46"', ' "-96.46"', ' "1996-07-22 00:00:00"']
INFO - Row #24->  ['New York', '41', 'Bill King', '546 College Av.', 'Deleted', ' "40.47"', ' "-73.58"', ' "1996-07-22 00:00:00"']
INFO - Row #25->  ['Oslo', '45', 'Janet May', '396 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #26->  ['Paris', '18', 'Sylvia Fuller', '158 - 20th Ave.', 'Trial', ' "48.48"', ' "2.20"', ' "1996-07-22 00:00:00"']
INFO - Row #27->  ['San Francisco', '48', 'Robert White', '549 Seventh Av.', 'Active', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #28->  ['Paris', '25', 'Sylvia Steel', '269 College Av.', 'Suspended', ' ""', ' ""', ' "1996-07-22 00:00:00"']
INFO - Row #29->  ['San Francisco', '7', 'James Peterson', '231 Upland Pl.', 'Active', ' "37.47"', ' "-122.26"', ' "1996-12-12 00:00:00"']
INFO - Row #30->  ['Oslo', '42', 'Robert Ott', '503 Seventh Av.', 'Trial', ' "59.57"', ' "10.42"', ' "1996-09-09 00:00:00"']

3 Writer 对象

Writer 对象可以让我们把数据写入 CSV 文件。

import csv
import os

'''
写入 csv
@author Deniro Li
'''

os.chdir('F:/temp')

output_file = open('output.csv', 'w', newline='')
output_writer = csv.writer(output_file)
output_writer.writerow(['网页', '咨询', '视频'])
output_writer.writerow(['图片', '知道', '文库'])
output_file.close()

运行结果:

  1. 首先调用 open()并传入’w’,以写模式打开一个新文件;
  2. 然后使用 csv.writer() 函数,创建一个 Writer 对象;
  3. 接着写入数据;
  4. 最后关闭这个文件。

在 Windows 上,需要为 open() 函数的 newline 关键字参数传入一个空字符串。如果没有设置 newline 参数, output.csv 中的行距将变为两倍,如下图所示。

如果写入的内容包含逗号,那么 csv 模块会自动加上双引号,对其进行转义,如下例所示。

output_writer.writerow(['贴吧,采购', '知道', '文库'])

运行结果:

4 delimiter 和 lineterminator

我们也可以利用 delimiter ,来制作 TSV 文件,TSV 是Tab-separated values的缩写,即以制表符作为分隔符的文件;利用 lineterminator 参数来设定行距。

tsv_file = open('output.tsv', 'w', newline='')
output_writer = csv.writer(tsv_file, delimiter='\t', lineterminator='\n\n\n')
output_writer.writerow(['网页', '咨询', '视频'])
output_writer.writerow(['图片', '知道', '文库'])
output_writer.writerow(['贴吧,采购', '知道', '文库'])
tsv_file.close()

运行结果:

这里利用 lineterminator=’\n\n\n’ 将行与行之间的字符变为三个换行符,效果就是实现了 3 倍行距。

发布了671 篇原创文章 · 获赞 766 · 访问量 99万+

猜你喜欢

转载自blog.csdn.net/deniro_li/article/details/105306391