如何在Python中聚合记录?

时间:2013-05-17 21:46:40

标签: python python-2.7

我有一个以下的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#并将其存储在DB中并编写sql查询。它非常慢,不被接受。谷歌搜索后,我听说python对于这些操作非常强大。我是Python的新手,开始玩代码。我非常感谢PYTHON大师帮助我得到上面提到的结果。

1 个答案:

答案 0 :(得分: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中完成它。处理大量数据流时,请使用generatorsiterators,不要使用file.readlines()just iterate。迭代器不会一次读取所有数据,而是在迭代它们时读取chunk-by-chunk,而不是更早。

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

  1. 按学生ID

    将记录分类到单独的“桶”(如bucket sort中)

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

  2. 按桶进行处理

  3. 合并

  4. grep就是一个例子。制作一个更好的脚本(awk或python),它将按学生ID过滤,例如,过滤所有ID< 1000,后来1000< ID< 2000年等。你可以安全地做到这一点,因为你的每个学生的记录是不相交的。