如何使输出 csv 文件的文件名等于列的内容
How do I make the filename of the output csv file equal to the the content of a column
我有一个巨大的 csv 文件,里面有我们所有的学生花名册。所以,
1) 我想根据
课程名。 2) 如果我可以让输出 csv 文件的名称等于
课程名称(例如:Algebra1.csv),这将使我的生活如此丰富
更好的。是否可以遍历 csv 文件的 courses_column,当课程名称更改时,它会为该课程创建一个新的 csv 文件。我想我可以读取字典的键 'read_rosters' 然后做一个 while 循环?
csv 输入文件的示例如下所示:
学生名字,学生姓氏,Class 教师,课程名称,初级学习中心
johnny, doe, smith, algebra1, 在线
jane, doe, austin, geometry, campus
这是我目前的情况:
import os
import csv
path = "/PATH/TO/FILE"
with open(os.path.join(path, "student_rosters.csv"), "rU") as rosters:
read_rosters = csv.DictReader(rosters)
for row in read_rosters:
course_name = row['COURSES_COLUMN_HEADER']
csv_file = os.path.join(course_name, ".csv")
course_csv = csv.writer(open(csv_file, 'wb').next()
首先,这不是你想要的:
csv_file = os.path.join(course_name, ".csv")
它将在名为 course_name
的子目录中创建一个名为 .csv
的文件。你可能想要这样的东西:
csv_file = os.path.join(path, course_name + ".csv")
此外,以下有两个问题:(a) 不平衡的括号和 (b) writer
对象没有 next
方法:
course_csv = csv.writer(open(csv_file, 'wb').next()
试试看:
course_csv = csv.writer(open(csv_file, 'wb'))
然后,您需要将您选择的内容写入新文件,可能使用 writeheader
、writerow
或 writerows
方法:
course_csv.writeheader(something_of_your_choosing)
course_csv.writerow(something_else_of_your_choosing)
在您当前的代码中,您正在为您阅读的每一行打开一个输出 csv 文件。这会很慢,而且正如您目前所写的那样,它不会起作用。这是因为在打开文件时使用 "wb"
模式会删除文件中之前的所有内容。您可以使用 "a"
模式,但这仍然很慢。
如何最好地解决问题在一定程度上取决于您的数据。如果您可以依靠输入始终将具有相同课程的行彼此相邻,则可以使用 itertools
模块中的 groupby
轻松地将适当的行写在一起:
from itertools import groupby
from operator import itemgetter
with open(os.path.join(path, "student_rosters.csv"), "rb") as rosters:
reader = csv.DictReader(rosters)
for course, rows in groupby(reader, itemgetter('COURSES_COLUMN_HEADER')):
with open(os.path.join(path, course + ".csv"), "wb") as outfile:
writer = csv.DictWriter(outfile, reader.fieldnames)
writer.writerows(rows)
如果您不能依赖行的组织,您有几个选择。一种方法是将所有行读入列表,然后按课程对它们进行排序,并像上面的代码一样使用 itertools.groupby
。
另一种选择是继续一次只读取一行,并将每个输出行放入适当的文件中。我建议保留一个作者对象的字典,按课程名称索引。这可能是这样的:
writers = {}
with open(os.path.join(path, "student_rosters.csv"), "rb") as rosters:
reader = csv.DictReader(rosters)
for row in reader:
course = row['COURSES_COLUMN_HEADER']
if course not in writers:
outfile = open(os.path.join(path, course + ".csv"), "wb")
writers[course] = csv.DictWriter(outfile, reader.fieldnames)
writers[course].writerow(row)
如果您在生产中使用它,您可能希望添加一些代码以在完成文件后关闭它们,因为您不能使用 with
语句自动关闭它们。
在我上面的示例代码中,我已经让代码写出完整的行,就像它们在输入中一样。如果您不想这样,您可以将 DictWriter
的第二个参数更改为您要写入的列名序列。您还需要包含参数 extrasaction="ignore"
,以便在写入您想要的列时忽略行字典中的额外值。
我有一个巨大的 csv 文件,里面有我们所有的学生花名册。所以, 1) 我想根据 课程名。 2) 如果我可以让输出 csv 文件的名称等于 课程名称(例如:Algebra1.csv),这将使我的生活如此丰富 更好的。是否可以遍历 csv 文件的 courses_column,当课程名称更改时,它会为该课程创建一个新的 csv 文件。我想我可以读取字典的键 'read_rosters' 然后做一个 while 循环?
csv 输入文件的示例如下所示:
学生名字,学生姓氏,Class 教师,课程名称,初级学习中心
johnny, doe, smith, algebra1, 在线
jane, doe, austin, geometry, campus
这是我目前的情况:
import os
import csv
path = "/PATH/TO/FILE"
with open(os.path.join(path, "student_rosters.csv"), "rU") as rosters:
read_rosters = csv.DictReader(rosters)
for row in read_rosters:
course_name = row['COURSES_COLUMN_HEADER']
csv_file = os.path.join(course_name, ".csv")
course_csv = csv.writer(open(csv_file, 'wb').next()
首先,这不是你想要的:
csv_file = os.path.join(course_name, ".csv")
它将在名为 course_name
的子目录中创建一个名为 .csv
的文件。你可能想要这样的东西:
csv_file = os.path.join(path, course_name + ".csv")
此外,以下有两个问题:(a) 不平衡的括号和 (b) writer
对象没有 next
方法:
course_csv = csv.writer(open(csv_file, 'wb').next()
试试看:
course_csv = csv.writer(open(csv_file, 'wb'))
然后,您需要将您选择的内容写入新文件,可能使用 writeheader
、writerow
或 writerows
方法:
course_csv.writeheader(something_of_your_choosing)
course_csv.writerow(something_else_of_your_choosing)
在您当前的代码中,您正在为您阅读的每一行打开一个输出 csv 文件。这会很慢,而且正如您目前所写的那样,它不会起作用。这是因为在打开文件时使用 "wb"
模式会删除文件中之前的所有内容。您可以使用 "a"
模式,但这仍然很慢。
如何最好地解决问题在一定程度上取决于您的数据。如果您可以依靠输入始终将具有相同课程的行彼此相邻,则可以使用 itertools
模块中的 groupby
轻松地将适当的行写在一起:
from itertools import groupby
from operator import itemgetter
with open(os.path.join(path, "student_rosters.csv"), "rb") as rosters:
reader = csv.DictReader(rosters)
for course, rows in groupby(reader, itemgetter('COURSES_COLUMN_HEADER')):
with open(os.path.join(path, course + ".csv"), "wb") as outfile:
writer = csv.DictWriter(outfile, reader.fieldnames)
writer.writerows(rows)
如果您不能依赖行的组织,您有几个选择。一种方法是将所有行读入列表,然后按课程对它们进行排序,并像上面的代码一样使用 itertools.groupby
。
另一种选择是继续一次只读取一行,并将每个输出行放入适当的文件中。我建议保留一个作者对象的字典,按课程名称索引。这可能是这样的:
writers = {}
with open(os.path.join(path, "student_rosters.csv"), "rb") as rosters:
reader = csv.DictReader(rosters)
for row in reader:
course = row['COURSES_COLUMN_HEADER']
if course not in writers:
outfile = open(os.path.join(path, course + ".csv"), "wb")
writers[course] = csv.DictWriter(outfile, reader.fieldnames)
writers[course].writerow(row)
如果您在生产中使用它,您可能希望添加一些代码以在完成文件后关闭它们,因为您不能使用 with
语句自动关闭它们。
在我上面的示例代码中,我已经让代码写出完整的行,就像它们在输入中一样。如果您不想这样,您可以将 DictWriter
的第二个参数更改为您要写入的列名序列。您还需要包含参数 extrasaction="ignore"
,以便在写入您想要的列时忽略行字典中的额外值。