
在Python中处理CSV文件时,如果需要将原始文件中的每一行或特定行的数据提取出来,并保存到以行内容命名的独立CSV文件中,一个常见的需求是将特定字段作为新文件的文件名,并将其他字段写入到这个新文件中。
假设我们有一个包含Order Number、Date和File Name三列的CSV文件,目标是为每一行创建一个新的CSV文件,文件名取自File Name字段,新文件中只包含Order Number和Date字段,且不带表头。
最初尝试可能直接使用f.write()方法将字段内容写入文件。然而,这种方法存在一个核心问题:f.write()仅仅是写入字符串,它不会自动添加CSV文件所需的字段分隔符(如逗号)。这会导致所有字段内容被连接成一个单一的字符串,而不是以逗号分隔的多个字段。
错误示例(仅供理解问题,不建议使用):
立即学习“Python免费学习笔记(深入)”;
import csv
# 假设TestExport.csv存在于指定路径
# with open("//server2/shared/Data/TestExport.csv",'r') as csvfile:
# reader = csv.DictReader(csvfile)
# for row in reader:
# file_name ='{0}.csv'.format(row['FileName'])
# with open(file_name, 'w') as f:
# f.write(row['Order Number'])
# f.write(row['Date'])上述代码的问题在于f.write(row['Order Number'])和f.write(row['Date'])会将两个字符串直接连接起来,例如123452023-01-01,而不是12345,2023-01-01。
解决上述问题的关键在于使用Python内置csv模块提供的csv.writer对象。csv.writer专门用于处理CSV格式的写入,它能够自动处理字段分隔符和行结束符。
核心改进点:
正确实现示例:
import csv
# 假设TestExport.csv是你的源文件
source_csv_path = "//server2/shared/Data/TestExport.csv"
with open(source_csv_path, 'r', encoding='utf-8') as in_f: # 建议指定编码
reader = csv.DictReader(in_f)
for row in reader:
# 根据'FileName'字段生成新CSV的文件名
file_name = '{0}.csv'.format(row['FileName'])
# 以写入模式打开新文件,并指定newline=''
with open(file_name, 'w', newline='', encoding='utf-8') as out_f: # 建议指定编码
# 创建csv写入器,指定逗号为分隔符
writer = csv.writer(out_f, delimiter=',')
# 写入Order Number和Date字段。writerow接受一个列表
writer.writerow([row['Order Number'], row['Date']])
print("所有行已成功拆分并写入独立CSV文件。")这段代码能够正确地将每一行数据拆分并写入到各自的CSV文件中,每个新文件只包含Order Number和Date两个字段,并以逗号分隔。
上述解决方案虽然正确,但存在一个潜在问题:如果源CSV文件中有两行或多行具有相同的File Name字段值,那么后一行的数据将覆盖前一行的数据,因为每次循环都会重新打开并清空同名文件。此外,频繁地打开和关闭文件也可能影响性能。
为了解决这个问题,我们可以采用更高级的策略:
健壮的解决方案示例:
import csv
import contextlib
source_csv_path = "//server2/shared/Data/TestExport.csv"
with open(source_csv_path, 'r', encoding='utf-8') as in_f:
# writers字典用于存储每个文件对应的csv.writer对象
# 键是文件名,值是对应的csv.writer实例
writers = {}
# 使用ExitStack来管理所有打开的文件对象
with contextlib.ExitStack() as stack:
reader = csv.DictReader(in_f)
for row in reader:
file_name = '{0}.csv'.format(row['FileName'])
# 尝试从writers字典中获取当前文件名的写入器
writer = writers.get(file_name)
# 如果该文件名的写入器尚未创建
if writer is None:
# 使用stack.enter_context()打开新文件。
# ExitStack会负责在with块结束时关闭此文件。
out_f = stack.enter_context(open(file_name, 'w', newline='', encoding='utf-8'))
# 创建新的csv写入器并存储到writers字典中
writer = csv.writer(out_f)
writers[file_name] = writer
# (可选)为新创建的文件写入表头
# 如果不需要表头,可以删除下面这行
writer.writerow(['OrderNumber', 'Date'])
# 使用获取到的(或新创建的)写入器写入数据行
writer.writerow([row['Order Number'], row['Date']])
print("所有行已成功拆分并写入独立CSV文件,重复文件名的数据已追加。")通过本教程,我们学习了如何使用Python的csv模块将一个CSV文件按行拆分为多个独立的CSV文件。从基础的csv.writer使用到更高级的contextlib.ExitStack和字典组合,我们解决了文件名冲突和资源管理问题,确保了数据拆分过程的准确性、健壮性和高效性。掌握这些技术将帮助你在处理CSV数据时更加灵活和专业。
以上就是使用Python将CSV文件按行拆分为多个独立文件并妥善管理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号