如何使输出csv文件的文件名等于列的内容

时间:2015-01-27 23:00:45

标签: python csv

我有一个巨大的csv文件,其中包含我们所有的学生名单。所以, 1)我想将名单分成较小的csv文件 课程名。 2)如果我可以输出csv文件的名称等于 课程名称(例如:Algebra1.csv),这将使我的生活如此之多 更好。是否可以遍历csv文件的courses_column,当​​课程名称发生变化时,它会为该课程创建一个新的csv文件。我想我可以阅读字典'read_rosters'的键然后做一个while循环?

csv输入文件的示例如下所示:

学生名,学生姓,班主任,课程名称,主要学习中心

johnny,doe,smith,algebra1,online

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()

2 个答案:

答案 0 :(得分:1)

在当前代码中,您将为您阅读的每一行打开输出csv文件。这将是缓慢的,并且,正如您目前所写,它将无法正常工作。这是因为在打开文件时使用"wb"模式会删除之前文件中的所有内容。您可以使用"a"模式,但这仍然很慢。

如何最好地解决问题取决于您的数据。如果您可以依赖输入始终将具有相同路线的行彼此相邻,则可以使用groupby模块中的itertools轻松地将相应的行一起写出:

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",以便在您想要的列被写入时,将忽略行dicts中的额外值。

答案 1 :(得分:0)

首先,这不是你想要的:

csv_file = os.path.join(course_name, ".csv")

它将在名为.csv的子目录中创建名为course_name的文件。你可能想要这样的东西:

csv_file = os.path.join(path, course_name + ".csv")

此外,以下有两个问题:(a)不平衡的parens和(b)writer个对象没有next方法:

course_csv = csv.writer(open(csv_file, 'wb').next()

尝试改为:

course_csv = csv.writer(open(csv_file, 'wb'))

然后,您需要将您选择的内容写入新文件,可能使用writeheaderwriterowwriterows方法:

course_csv.writeheader(something_of_your_choosing)
course_csv.writerow(something_else_of_your_choosing)