1

我有一个以下 csv 文件(每行是动态字符数,但列是固定的......希望我有意义)

   **001**     Math        **02/20/2013**  A

   **001**     Literature  **03/02/2013**  B

   **002**     Biology     **01/01/2013**  A

   **003**     Biology     **04/08/2013**  A

   **001**     Biology     **05/01/2013**  B

   **002**     Math        **03/10/2013**  C

我正在尝试以以下格式将结果放入另一个 csv 文件中,该文件按学生 ID 分组,并按日期升序排列。

   001,#Math;A;02/20/2013#Biology;B;05/01/2013#Literature;B;03/02/2013

   002,#Biology;A;01/01/2013#Math;C;03/10/2013

   003,#Biology;A;04/08/2013

但是有一个限制。输入文件很大,大约有 2 亿行。我尝试使用 c# 并将其存储在数据库中并编写 sql 查询。它非常缓慢且不被接受。谷歌搜索后,我听说 python 对于这些操作非常强大。我是 Python 新手,开始玩代码。我真的很感谢 PYTHON 大师帮助我获得上面提到的结果。

4

1 回答 1

2
content='''
   **001**     Math        **02/20/2013**  A

   **001**     Literature  **03/02/2013**  B

   **002**     Biology     **01/01/2013**  A

   **003**     Biology     **04/08/2013**  A

   **001**     Biology     **05/01/2013**  B

   **002**     Math        **03/10/2013**  C
'''

from collections import defaultdict

lines = content.split("\n")
items_iter = (line.split() for line in lines if line.strip())

aggregated = defaultdict(list)

for items in items_iter:
    stud, class_, date, grade = (t.strip('*') for t in items)
    aggregated[stud].append((class_, grade, date))

for stud, data in aggregated.iteritems():
    full_grades = [';'.join(items) for items in data]
    print '{},#{}'.format(stud, '#'.join(full_grades))

输出:

003,#Biology;A;04/08/2013
002,#Biology;A;01/01/2013#Math;C;03/10/2013
001,#Math;A;02/20/2013#Literature;B;03/02/2013#Biology;B;05/01/2013

当然,这是一个丑陋的 hackish 代码,只是为了向您展示如何在 python 中完成它。在处理大量数据流时,请使用生成器迭代器,不要使用file.readlines()只需迭代。迭代器不会一次读取所有数据,而是在您迭代它们时逐块读取,而不是更早。

如果您担心 200m 记录是否适合内存,请执行以下操作:

  1. 按学生 ID将记录排序到单独的“桶”中(如桶排序)

    cat all_records.txt | grep 001 > stud_001.txt # do if for other students also

  2. 按桶进行处理

  3. 合并

grep只是例子。制作一个更高级的脚本(awk 或 python),它将按学生 ID 过滤,例如,过滤 ID < 1000、稍后 1000 < ID < 2000 等的所有内容。您可以安全地执行此操作,因为您的每个学生的记录是不相交的。

于 2013-05-17T22:03:44.413 回答