Python 处理 CSV 文件完全指南:从入门到精通

在日常的数据处理任务中,你肯定会经常遇到 CSV(逗号分隔值)文件。这种格式因其简单、通用且易于被 Excel 等表格软件打开而广受欢迎。作为一名 Python 开发者,掌握如何高效地读写 CSV 文件是一项必不可少的技能。在这篇文章中,我们将深入探讨 Python 内置的 csv 模块,不仅会学习基础的读写操作,还会分享一些在实际开发中积累的经验、性能优化技巧以及常见错误的解决方案。

什么是 CSV 文件?

在开始写代码之前,让我们先明确一下什么是 CSV 文件。简单来说,一个 CSV (逗号分隔值) 文件 就是一种纯文本文件,它使用特定的结构来存储表格数据。在文件中,每一行代表一条数据记录,而每条记录中的字段则由逗号分隔。虽然名字里带著“逗号”,但在某些场景下,分隔符也可能是分号或制表符,但逗号是最常见的标准。

因其简单性和可读性,CSV 常被用于在不同系统(如数据库、电子表格应用程序)之间交换数据。虽然 Python 中有强大的 INLINECODEcbc865a5 库可以处理数据,但在处理简单的数据导入导出任务时,内置的 INLINECODE5d096eda 模块轻量且高效,无需安装额外的依赖。

准备工作:导入模块

在 Python 中处理 CSV 文件,我们主要依赖标准库中的 csv 模块。这意味着你不需要安装任何第三方库,直接导入即可使用。接下来的所有示例都基于以下导入语句:

import csv

读取 CSV 文件:基础与进阶

使用 csv.reader 对象读取

当我们需要从 CSV 文件中读取数据时,最直接的方法是使用 INLINECODE3b25d629 模块提供的 INLINECODEe787e62c 对象。这个过程通常包含三个步骤:打开文件、创建 reader 对象、遍历数据。

让我们通过一个例子来看看具体是如何操作的。假设我们有一个名为 aapl.csv 的文件(你可以从 这里 下载这个数据集进行练习),里面存储了一些股票数据。

核心步骤解析:

  • 打开文件:使用 Python 内置的 INLINECODE9ac9be0e 函数。为了确保代码的健壮性,我们强烈建议使用 INLINECODE7b7ddf71 语句。这是一个上下文管理器,它可以自动处理文件的打开和关闭,即使在读取过程中发生异常,文件也能被安全关闭,避免资源泄露。
  • 创建 Reader:将文件对象传递给 csv.reader(),它会返回一个可迭代的 reader 对象。
  • 读取数据:Reader 对象是一个迭代器,我们可以使用 next() 函数跳过表头,或者通过循环遍历每一行数据。

代码示例:

import csv

# 文件名
filename = "aapl.csv"
fields = []  # 用于存储列名(表头)
rows = []    # 用于存储实际数据行

# 使用 with 语句以读取模式 (‘r‘) 打开文件
with open(filename, ‘r‘, encoding=‘utf-8‘) as csvfile:
    # 创建 csv reader 对象
    csvreader = csv.reader(csvfile)

    # 从 reader 对象中提取第一行作为表头
    fields = next(csvreader)

    # 遍历 reader 对象的剩余部分
    for row in csvreader:
        rows.append(row)

    # csvreader.line_num 属性可以告诉我们已经读取了多少行
    print(f"Total no. of rows: {csvreader.line_num}")

# 打印表头
print(‘Field names are: ‘ + ‘, ‘.join(fields))

print(‘
First 5 rows are:
‘)
# 格式化打印前 5 行数据
for row in rows[:5]:
    for col in row:
        print("%10s" % col, end=" ")
    print(‘
‘)

输出结果:

程序会首先显示列的总数,然后列出前5行的数据。通过这种方式,我们可以快速验证数据是否被正确导入。

使用 csv.DictReader 将数据读取为字典

虽然上面的 INLINECODE28d8bce8 对象很好用,但在实际编程中,通过索引(如 INLINECODE7de3f5fb, row[1])来访问数据往往不够直观且容易出错。想象一下,如果列的顺序变了,你的代码逻辑可能就会崩溃。

为了解决这个问题,我们可以使用 csv.DictReader。它会将每一行数据映射到一个字典中,其中表头(第一行)自动成为字典的键。这样你就可以通过列名来访问数据,代码的可读性和维护性都会大大提升。

假设场景:

我们有一个 employees.csv 文件,内容如下:

name,department,birthday_month
John Smith,HR,July
Alice Johnson,IT,October
Bob Williams,Finance,January

代码示例:

import csv

# 以读取模式打开文件
with open(‘employees.csv‘, mode=‘r‘, encoding=‘utf-8‘) as file:
    # 创建 DictReader 对象
    csv_reader = csv.DictReader(file)

    data_list = []  # 用于存储字典对象的列表
    for row in csv_reader:
        # 此时 row 是一个字典,例如 {‘name‘: ‘John Smith‘, ‘department‘: ‘HR‘, ...}
        data_list.append(row)

# 遍历并打印数据,直接使用列名访问
for data in data_list:
    print(data)

输出结果:

{‘name‘: ‘John Smith‘, ‘department‘: ‘HR‘, ‘birthday_month‘: ‘July‘}
{‘name‘: ‘Alice Johnson‘, ‘department‘: ‘IT‘, ‘birthday_month‘: ‘October‘}
{‘name‘: ‘Bob Williams‘, ‘department‘: ‘Finance‘, ‘birthday_month‘: ‘January‘}

你可以看到,通过 INLINECODE9fb102b9 来获取员工名字比通过 INLINECODE86f4a0b0 要清晰得多。

写入 CSV 文件:保存你的数据

学会了读取,接下来我们看看如何将数据写入 CSV 文件。这在生成报表或导出数据时非常有用。

使用 csv.writer 写入列表数据

要将数据写入 CSV 文件,我们需要以写入模式(INLINECODEb6783a8a)打开文件。注意:如果文件不存在,Python 会创建它;如果文件已存在,写入模式会覆盖原有内容。如果你希望追加数据,可以使用追加模式 INLINECODE7b531b72。

代码示例:

在这个例子中,我们将模拟一些大学记录并将其写入文件。

import csv

# 1. 定义表头和数据行
fields = [‘Name‘, ‘Branch‘, ‘Year‘, ‘CGPA‘]
rows = [
    [‘Nikhil‘, ‘COE‘, ‘2‘, ‘9.0‘],
    [‘Sanchit‘, ‘COE‘, ‘2‘, ‘9.1‘],
    [‘Aditya‘, ‘IT‘, ‘2‘, ‘9.3‘],
    [‘Sagar‘, ‘SE‘, ‘1‘, ‘9.5‘],
    [‘Prateek‘, ‘MCE‘, ‘3‘, ‘7.8‘],
    [‘Sahil‘, ‘EP‘, ‘2‘, ‘9.1‘]
]

filename = "university_records.csv"

# 2. 打开文件进行写入
with open(filename, ‘w‘, newline=‘‘, encoding=‘utf-8‘) as csvfile:
    # 创建 writer 对象
    csvwriter = csv.writer(csvfile)

    # 3. 写入表头
    csvwriter.writerow(fields)

    # 4. 写入多行数据 (writerows 复数形式,用于批量写入)
    csvwriter.writerows(rows)

print(f"数据已成功写入 {filename}")

关键技术点:

  • INLINECODE329bca03 参数:在 Windows 系统上,如果不加这个参数,你可能会发现写入的 CSV 文件中每行之间都有一个空行。设置 INLINECODEcdefc17f 可以防止这种情况发生,这是跨平台开发中的一个重要细节。
  • INLINECODE56128e01 vs INLINECODE9edea2b3:前者写入单行(通常用于表头),后者接受一个列表的列表并一次性写入多行数据,效率更高。

使用 csv.DictWriter 写入字典数据

正如读取时可以使用字典一样,写入时我们也可以使用 csv.DictWriter。当你手头的数据已经是字典格式(比如从 API 获取的 JSON 数据转换而来)时,这非常方便。

代码示例:

import csv

# 1. 准备字典数据
mydict = [
    {‘branch‘: ‘COE‘, ‘cgpa‘: ‘9.0‘, ‘name‘: ‘Nikhil‘, ‘year‘: ‘2‘},
    {‘branch‘: ‘COE‘, ‘cgpa‘: ‘9.1‘, ‘name‘: ‘Sanchit‘, ‘year‘: ‘2‘},
    {‘branch‘: ‘IT‘, ‘cgpa‘: ‘9.3‘, ‘name‘: ‘Aditya‘, ‘year‘: ‘2‘},
    {‘branch‘: ‘SE‘, ‘cgpa‘: ‘9.5‘, ‘name‘: ‘Sagar‘, ‘year‘: ‘1‘},
    {‘branch‘: ‘MCE‘, ‘cgpa‘: ‘7.8‘, ‘name‘: ‘Prateek‘, ‘year‘: ‘3‘},
    {‘branch‘: ‘EP‘, ‘cgpa‘: ‘9.1‘, ‘name‘: ‘Sahil‘, ‘year‘: ‘2‘}
]

filename = "university_records_dict.csv"

# 2. 定义字段名(这对于 DictWriter 至关重要)
fieldnames = [‘branch‘, ‘cgpa‘, ‘name‘, ‘year‘]

with open(filename, ‘w‘, newline=‘‘, encoding=‘utf-8‘) as csvfile:
    # 创建 DictWriter 对象,并指定字段名
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    # 3. 写入表头
    writer.writeheader()

    # 4. 写入数据
    writer.writerows(mydict)

print(f"字典数据已成功写入 {filename}")

实用技巧:

在使用 INLINECODE153f2c3f 时,如果你的字典中包含一些你不想写入文件的键,或者想控制写入顺序,定义清晰的 INLINECODEb2fc02f1 列表是必不可少的。INLINECODE8582c5ab 方法会根据 INLINECODE73c55783 的顺序将键名作为第一行写入文件。

实战技巧与最佳实践

在实际开发中,仅仅会调用 API 是不够的。处理 CSV 文件时,你可能会遇到各种“坑”。下面,让我们分享一些进阶技巧。

1. 处理包含分隔符的引号字段

设想一下,如果你的 CSV 文件中某个字段本身包含逗号(例如:INLINECODE2162b591),简单的 INLINECODEeeb6c3ca 就会把公司名拆开,导致数据错乱。标准的 CSV 格式使用引号来包裹这类特殊字段。

Python 的 INLINECODE464f5505 模块默认支持 INLINECODE1c4e9c9b,这意味着它会自动处理包含分隔符或换行符的字段。最佳实践是永远使用 csv 模块而不是手动操作字符串,因为它能处理这些复杂的边缘情况。

2. 处理不同的方言和分隔符

并不是所有的 CSV 文件都使用逗号分隔。在欧洲,分号(;)是标准的 CSV 分隔符。如果你的文件打不开,或者数据全都在一列里,请检查分隔符。

# 指定分隔符为分号
with open(‘european_data.csv‘, ‘r‘, encoding=‘utf-8‘) as f:
    reader = csv.reader(f, delimiter=‘;‘)
    for row in reader:
        print(row)

3. 读取大文件的性能优化

如果你遇到一个几百 MB 甚至 GB 级别的 CSV 文件,使用 rows = list(reader) 一次性将所有数据加载到内存中可能会导致程序崩溃(内存溢出)。

解决方案:利用生成器和逐行处理。不要试图把整个文件存入列表,而是直接遍历 reader 对象,逐行处理数据并存储到数据库或进行计算。

# 内存友好的处理方式
with open(‘huge_file.csv‘, ‘r‘, encoding=‘utf-8‘) as f:
    reader = csv.reader(f)
    for row in reader:
        # 仅在当前循环中处理这一行
        process_row(row) 
        # 循环结束后,这一行的数据就会被垃圾回收器回收

4. 统一处理换行符

在不同的操作系统(Linux vs Windows)之间传输 CSV 文件时,你可能会遇到换行符显示异常的问题(出现 ^M 符号或空行)。

解决方案:在 INLINECODEc75961e8 函数中显式使用 INLINECODE087756f8。这是 Python 官方文档强烈推荐的用法,它让 Python 的 csv 模块自己去处理行结束符,从而避免不一致的行为。

5. 编码问题

当你读取包含中文或特殊字符的 CSV 文件时,可能会遇到 UnicodeDecodeError。这通常是因为文件编码不是默认的 UTF-8 或系统默认编码。

解决方案:尝试指定编码格式。常见的中文编码有 INLINECODE1cbd1a96(带BOM的UTF-8有时候叫 INLINECODE571314e0)和 INLINECODE773108ab/INLINECODEf8b4c37c。如果默认打不开,试试 INLINECODE31fee564 或 INLINECODE844886f5。

6. 格式化输出数字

在之前的例子中,你可能注意到了 print("%10s" % col)。这是一种简单的格式化技巧,让输出的列对齐。在 Python 3.6+ 中,你还可以使用更现代的 f-string 语法:

for row in rows[:5]:
    for col in row:
        # 宽度为10,左对齐
        print(f"{col:<10}", end=" ")
    print()

总结

在本文中,我们全面探讨了如何使用 Python 处理 CSV 文件。从最基础的 INLINECODEe1c5ba8c 和 INLINECODEf5ff236d,到更符合工程实践的 INLINECODEa41558e8 和 INLINECODE4fe8f86b,甚至是处理大文件性能优化和常见编码问题,这些技能足以应对绝大多数开发场景。

关键要点回顾:

  • 使用 csv 模块:不要手动解析文件,它内置了对引号、换行符和转义字符的处理。
  • 善用 DictReader/DictWriter:通过列名访问数据比索引更安全、更易读。
  • 使用 INLINECODEbdbc5c12:确保文件资源被正确释放,使用 INLINECODE77588cf9 避免多余的空行。
  • 注意编码:遇到乱码时,第一时间检查文件编码(如 UTF-8 或 GBK)。

下一步建议:

虽然 INLINECODE9f818c2c 模块对于中小型任务非常完美,但如果你需要进行复杂的数据分析(如数据透视、缺失值处理、矩阵运算),那么学习 Pandas 库将是你进阶之路的下一步。Pandas 的 INLINECODEc64b853a 和 to_csv() 提供了更加强大且灵活的数据处理能力。

希望这篇文章能帮助你更好地处理手中的数据!如果你在实践中遇到其他问题,欢迎随时查阅 Python 官方文档或社区资源进行深入探索。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/31000.html
点赞
0.00 平均评分 (0% 分数) - 0