读写 CSV 文件

CSV文件是最常用的数据文档格式之一,由于几乎所有数据表格软件都能处理这种通用格式的文档。因此它的使用非常广泛。作为产品经理,你使用的大量数据,如:用户列表、销售记录、需求清单等等,都可能以这种文件格式存储。

通过学习用 Python 读写 CSV 文件,你可以:

  • 
快速从数据中提取有用的信息。
  • 自动化重复的数据操作任务。
  • 提高数据处理效率,为决策提供支持。

什么是 CSV 文件?

CSV 文件是一种以纯文本形式存储表格数据的格式。它以逗号作为字段分隔符,用换行符分隔不同的记录。CSV文件结构简单,易于理解和生成,广泛应用于数据交换、数据备份等领域。以下是一个示例:

Name, Age, Department
Alice, 30, Engineering
Bob, 25, Marketing
Charlie, 35, Sales

在示例中我们看到:

  • 每一行表示一条记录。
  • 每一列由逗号分隔。

Python 中处理 CSV 的基础

Python 提供了一个内置的 csv 模块,用于高效处理 CSV 文件。我们可以使用它来:

  • 读取 CSV 文件。
  • 写入 CSV 文件。
  • 修改 CSV 文件。

读取文件的示例:读取用户反馈数据

场景:产品经理需要查看用户反馈数据,了解用户最关心的问题。

CSV 数据示例:

Name, Age, Department
Alice, 30, Engineering
Bob, 25, Marketing
Charlie, 35, Sales
代码实现:
import csv

# 读取用户反馈数据
with open("feedback.csv", "r", encoding="utf-8") as file:
    reader = csv.reader(file)
    for row in reader:
        print(f"用户ID:{row[0]},反馈:{row[1]}")

输出结果:

用户ID:101,反馈:Very user-friendly!
用户ID:102,反馈:Needs more customization options.
用户ID:103,反馈:Great performance, but occasional crashes.

写入文件的示例:筛选指定内容并生成新文件

场景:产品经理需要从上述CSV文件里表格里“Feedback”栏中查找指定关键词的条目(例如:有“but”一词的条目,)把这些数据写入一个新的 CSV 文件:“but.csv”。

代码实现:

import csv

# 输入和输出文件名
input_file = "feedback.csv"
output_file = "but.csv"

# 打开输入文件进行读取
with open(input_file, "r", encoding="utf-8") as infile:
    reader = csv.reader(infile)
    header = next(reader)  # 读取表头
    
    # 打开输出文件进行写入
    with open(output_file, "w", newline="", encoding="utf-8") as outfile:
        writer = csv.writer(outfile)
        writer.writerow(header)  # 写入表头

        # 遍历输入文件的每一行
        for row in reader:
            if "but" in row[1]:  # 检查 Feedback 栏中是否包含 "but"
                writer.writerow(row)  # 将符合条件的行写入输出文件

print(f"筛选完成,结果已保存到 '{output_file}' 文件中。")

运行程序后,生成的 but.csv 文件内容为:

User ID, Feedback
103, Great performance, but occasional crashes.

修改文件的示例:添加日期栏

场景:现在产品经理想修改这个新的 CSV 文件:“but.csv”,为表格添加一列日期,并统一输入当天的日期。

代码实现:

import csv
from datetime import datetime

# 输入文件名和输出文件名
input_file = "but.csv"
output_file = "but_with_date.csv"

# 获取当前日期
current_date = datetime.now().strftime("%Y-%m-%d")

# 打开输入文件进行读取
with open(input_file, "r", encoding="utf-8") as infile:
    reader = csv.reader(infile)
    rows = list(reader)  # 将数据读取到列表中

    # 添加新列名到表头
    rows[0].append("Date")

    # 为每行数据添加当前日期
    for row in rows[1:]:
        row.append(current_date)

# 打开输出文件进行写入
with open(output_file, "w", newline="", encoding="utf-8") as outfile:
    writer = csv.writer(outfile)
    writer.writerows(rows)

print(f"已成功将日期列添加到文件 '{output_file}' 中!")

在上面代码中,我们获取当前日期时使用了 datetime ,这是一个 Python 的内置模块,用于处理日期和时间。 datetime.now()datetime 类中的方法,用来获取当前的日期和时间。

  • strftime()datetime 提供的方法,用于将日期和时间对象转换为 字符串,并按指定格式输出。
  • "%Y-%m-%d" 是格式化字符串,定义了输出的日期格式:
    1. %Y:表示四位年份(如 2024)。
    2. %m:表示两位的月份(如 11)。
    3. %d:表示两位的日期(如 19)。

datetime.now().strftime("%Y-%m-%d") 获取当天日期,并格式化为 YYYY-MM-DD 格式。这样做的目的是将日期格式化为字符串,适合用于文件命名、数据标记、日志记录等。

随后,程序开始读取原始 CSV 文件:打开 but.csv 文件并读取数据,存储到一个列表 rows 中。

注意,这里我们通过 rows[0].append("Date") 在表头添加新列名 “Date”。表头(Header) 是第一行内容,通常用于描述列的含义。在我们的案例里,表头 就是 User IDFeedback,分别对应每一列的数据。表头不仅标记每列的含义,同时通过表头,程序可以通过列名直接找到对应列的数据,而不需要记住列的索引号。因此,在实际的开发中,表头的修改、添加或校验都是常见的任务。在我们的案例里,我们增加了一个新列名 Date 到新表格的表头里。

接下来,程序添加日期到每一行。它遍历数据的每一行(从 rows[1:] 开始),在行尾添加当天的日期。

最后,程序将更新后的数据写入新的 CSV 文件 but_with_date.csv

修改后的文件(but_with_date.csv):

User ID, Feedback, Date
103, Great performance, but occasional crashes., 2022-10-19

以上三个示例程序虽然简单,但却展示了 Python 在处理 CSV 文件时的强大能力。在日常工作汇总,产品经理能够直接从 CSV 文件执行复杂的数据分析任务,如过滤、分组和汇总数据。而且非常高效。

不仅如此,Python 的多功能性使产品经理能够自动执行重复性任务。例如,他们可以编写脚本来读取多个 CSV 文件,将它们组合起来,并准备数据以供进一步分析或报告。这种自动化在处理大型数据集或定期数据更新时特别有用。我们来看一个简单的案例:

集成和自动化的示例:合并2个 CSV 文件

场景:现在产品经理想按“but_with_date.csv”的表头设置,将“feedback.csv”和“but_with_date.csv”2个文件合并为一个新文件:“all.csv”。

代码实现:

import csv

# 输入文件名
file1 = "feedback.csv"
file2 = "but_with_date.csv"
output_file = "all.csv"

# 打开第一个文件并读取数据
with open(file1, "r", encoding="utf-8") as f1, open(file2, "r", encoding="utf-8") as f2:
    reader1 = csv.reader(f1)
    reader2 = csv.reader(f2)
    
    # 获取两个文件的内容
    rows1 = list(reader1)
    rows2 = list(reader2)

    # 使用第二个文件的表头
    header = rows2[0]
    data1 = rows1[1:]  # 第一个文件的数据(跳过表头)
    data2 = rows2[1:]  # 第二个文件的数据(跳过表头)

    # 为第一个文件的数据添加缺失的列值(如 "Date" 列)
    for row in data1:
        if len(row) < len(header):  # 如果列不足,填充空值
            row.append("")

# 将合并后的数据写入新文件
with open(output_file, "w", newline="", encoding="utf-8") as outfile:
    writer = csv.writer(outfile)
    writer.writerow(header)  # 写入表头
    writer.writerows(data1)  # 写入第一个文件的数据
    writer.writerows(data2)  # 写入第二个文件的数据

print(f"文件已合并,生成新文件:{output_file}")

在上述程序中,我们先使用 csv.reader 分别读取 feedback.csvbut_with_date.csv 两个文件的内容。

然后我们会将每个文件的表头和数据分开处理。我们默认使用 but_with_date.csv 的表头(包含 Date 列)。然后为另一个文件 feedback.csv 的数据补充空列。如果 feedback.csv 的列数不足(例如缺少 Date 列),通过 row.append("") 添加空值以对齐表头。

最后,程序使用 csv.writer 创建新文件 all.csv。这里会先写入表头,然后依次写入两个文件的所有数据。

另外,在实际工作中,你可以在这个程序基础上扩展,比如合并多个文件。或者灵活地补充缺失列的默认值(如填充 “Unknown Date”或给出某个日期)。有时我们也可能需要动态检测并对齐表头差异,以及根据需求调整数据顺序,从而实现两个 CSV 文件的无缝合并,生成统一格式的输出文件,满足多场景的数据整合需求。

常见问题与解决方案

1. 数据中包含逗号
问题:数据中包含逗号(如 New York, USA )可能导致列错位。
解决方法:在 CSV 文件中使用引号包裹数据(Python 会自动处理):

writer.writerow(['"New York, USA"', 5000])

2. 文件编码问题

  • 问题:处理非 UTF-8 编码的 CSV 文件时可能出现乱码。
  • 解决方法:显式指定编码,例如 encoding="gbk"

3. 缺少表头

  • 问题:生成的 CSV 文件没有表头。
  • 解决方法:使用 writer.writeheader() 添加表头。

练习:

    1. 创建一个包含以下数据的 CSV 文件:
      • 产品名称、售价、销量。
      • 示例数据:Product A, 50, 200
    2. 读取该文件并计算总收入。
    3. 批量向文件中追加新数据(如新增产品信息)。

你可以自己尝试撰写,也可以设计自己的提示词,让大语言模型帮你完成这3个编程任务。试着比较你们写的内容有什么不同。

AI 助教

提示:您可在此提出学习中遇到的问题。回答由 AI 生成,可能存在错误,请注意甄别。