pin_drop当前位置:知识文库 ❯ 图文
Python读写CSV完整教程
目录
一、CSV文件操作概述
CSV(Comma-Separated Values)是一种简单、通用的数据存储格式,以纯文本形式存储表格数据。每行代表一条记录,字段之间通常以逗号分隔。Python内置的 csv 模块提供了完整的CSV文件读写功能。
使用场景包括:数据导入导出、数据分析预处理、Excel数据迁移、日志记录等。相比直接操作纯文本,csv模块能自动处理字段中的逗号、引号、换行符等特殊情况。
二、CSV模块语法基础
Python的csv模块提供了以下核心API:
-
csv.reader():读取CSV文件,返回迭代器,每行是一个列表
-
csv.writer():写入CSV文件,支持writerow和writerows方法
-
csv.DictReader():以字典方式读取CSV,键名为表头
-
csv.DictWriter():以字典方式写入CSV,需要指定字段名
代码示例
import csv
# 读取CSV的基本语法
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
# 写入CSV的基本语法
with open("output.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
writer.writerow(["姓名", "年龄", "城市"])
writer.writerow(["张三", "28", "北京"])
三、读取CSV文件的基本用法
使用csv.reader读取
代码示例
import csv
# 准备示例CSV文件内容:
# 姓名,年龄,城市
# 张三,28,北京
# 李四,32,上海
# 王五,25,广州
with open("students.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f)
# 读取表头
header = next(reader)
print(f"表头: {header}") # ['姓名', '年龄', '城市']
# 遍历数据行
for row in reader:
print(f"姓名: {row[0]}, 年龄: {row[1]}, 城市: {row[2]}")
自定义分隔符
代码示例
import csv
# 读取以制表符分隔的文件
with open("data.tsv", "r", encoding="utf-8") as f:
reader = csv.reader(f, delimiter="\t")
for row in reader:
print(row)
# 读取以分号分隔的文件(欧洲常用)
with open("data_eu.csv", "r", encoding="utf-8") as f:
reader = csv.reader(f, delimiter=";")
for row in reader:
print(row)
四、写入CSV文件的基本用法
单行写入与批量写入
代码示例
import csv
# 写入CSV文件
data = [
["姓名", "年龄", "成绩"],
["张三", "28", "85"],
["李四", "32", "92"],
["王五", "25", "78"],
]
with open("grades.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
# 单行写入
writer.writerow(data[0]) # 写入表头
# 批量写入
writer.writerows(data[1:]) # 写入所有数据行
print("CSV文件写入完成!")
自定义引号与分隔符
代码示例
import csv
with open("custom.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.writer(
f,
delimiter="|", # 使用|作为分隔符
quotechar='"', # 使用双引号包裹字段
quoting=csv.QUOTE_MINIMAL # 仅在必要时添加引号
)
writer.writerow(["产品", "价格", "描述"])
writer.writerow(["笔记本", "5999", '高性能,"轻薄便携"'])
五、DictReader与DictWriter
当CSV文件有表头时,使用字典方式操作更为直观,可以通过列名而非索引来访问数据:
DictReader读取
代码示例
import csv
# 使用DictReader读取,自动将表头作为字典的键
with open("employees.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
# 直接使用列名访问,无需记住索引位置
print(f"姓名: {row['姓名']}, 部门: {row['部门']}, 薪资: {row['薪资']}")
# 也可以做数据筛选
if int(row['薪资']) > 8000:
print(f" -> {row['姓名']} 是高薪员工")
DictWriter写入
代码示例
import csv
# 使用DictWriter写入,以字典形式提供数据
fieldnames = ["姓名", "部门", "薪资"]
employees = [
{"姓名": "张三", "部门": "技术部", "薪资": "12000"},
{"姓名": "李四", "部门": "市场部", "薪资": "9000"},
{"姓名": "王五", "部门": "人事部", "薪资": "8500"},
]
with open("employees_out.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
# 写入表头
writer.writeheader()
# 逐行写入
for emp in employees:
writer.writerow(emp)
# 也可以批量写入
# writer.writerows(employees)
print("员工数据写入完成!")
六、综合实战示例
CSV数据转换与统计
代码示例
import csv
from collections import defaultdict
# 读取销售数据并统计每个地区的总销售额
def analyze_sales(filename):
region_sales = defaultdict(float)
with open(filename, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
region = row["地区"]
sales = float(row["销售额"])
region_sales[region] += sales
# 将统计结果写入新的CSV
with open("region_summary.csv", "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["地区", "总销售额"])
writer.writeheader()
for region, total in sorted(region_sales.items()):
writer.writerow({"地区": region, "总销售额": f"{total:.2f}"})
print(f"{region}: ¥{total:.2f}")
# 示例数据
# 地区,产品,销售额
# 华东,电脑,12000.50
# 华南,手机,8500.00
# 华东,手机,6300.00
# 华北,电脑,15000.00
analyze_sales("sales.csv")
CSV文件合并
代码示例
import csv
import glob
def merge_csv_files(pattern, output_file):
"""合并多个具有相同结构的CSV文件"""
first_file = True
with open(output_file, "w", encoding="utf-8", newline="") as out_f:
writer = csv.writer(out_f)
for filename in glob.glob(pattern):
with open(filename, "r", encoding="utf-8") as in_f:
reader = csv.reader(in_f)
for i, row in enumerate(reader):
# 只在第一个文件中写入表头
if first_file and i == 0:
writer.writerow(row)
elif i > 0: # 跳过其他文件的表头
writer.writerow(row)
first_file = False
print(f"合并完成,结果已保存到 {output_file}")
# 合并所有month_*.csv文件
merge_csv_files("month_*.csv", "all_data.csv")
七、CSV与Pandas对比
八、注意事项
注意1:写入CSV时必须指定
newline=""参数,否则在Windows系统上会出现空行问题。这是Python 3中csv模块的常见陷阱。
注意2:处理包含中文的CSV文件时,务必指定
encoding="utf-8"。在Windows上由Excel生成的CSV可能使用gbk编码,读取时需要相应调整。
注意3:csv.reader 返回的每行数据都是字符串列表,如果需要数值类型的数据,必须手动进行类型转换,例如
int(row[1])或float(row[2])。
注意4:DictWriter 必须在构造时通过
fieldnames参数指定列的顺序。如果字典中包含 fieldnames 之外的键,需要通过extrasaction参数处理(默认为 "raise" 会报错)。
九、小结
-
内置模块:Python的csv模块是内置的标准库,无需安装即可使用,提供了完整的CSV读写功能。
-
四种核心API:reader/writer 基于列表操作,DictReader/DictWriter 基于字典操作,后者在有表头的场景下更加直观。
-
编码与换行:处理中文时使用utf-8编码,写入时务必指定newline=""避免Windows上的空行问题。
-
场景选择:简单的CSV操作用csv模块足够,复杂的数据分析可以考虑pandas库。
十、练习题
练习1
编写程序,读取一个包含学生成绩信息的CSV文件(姓名、语文、数学、英语),计算每位学生的总分和平均分,并写入新的CSV文件。
练习2
编写一个函数,将Python列表中的字典数据导出为CSV文件,要求支持自定义字段顺序和编码格式。
练习3
编写程序,比较两个具有相同结构的CSV文件,找出数据行之间的差异(新增、删除、修改),并将差异结果输出到第三个CSV文件中。
常见问题
为什么写入CSV时要加newline=""?
在Windows系统上,Python默认会将\n转换为\r\n写入文件。而csv模块自己已经处理了换行,如果不禁用这个转换(通过newline=""),就会出现每行之间多一个空行的问题。
如何读取没有表头的CSV文件?
使用csv.reader直接读取即可,每行返回一个列表。如果想用DictReader但没有表头,可以传入fieldnames参数:`csv.DictReader(f, fieldnames=["col1", "col2", "col3"])`。
CSV文件中字段包含逗号怎么办?
csv模块会自动处理这种情况。当字段中包含逗号时,writer会自动用双引号将字段包裹起来;reader读取时也会自动解析被引号包裹的字段。无需手动处理。
csv模块和pandas该选哪个?
如果只是简单地读写CSV文件,使用内置的csv模块即可,无需额外依赖。如果需要进行数据筛选、分组聚合、数据清洗等分析操作,pandas会更加方便高效。
本文涉及AI创作
内容由AI创作,请仔细甄别