以内存有效的方式将列添加到.csv文件

时间:2016-07-22 17:13:58

标签: python csv

好的,我无法在其他任何地方找到答案,所以我想我会问。

我正在处理一些目前大约有7400万行的.csv文件,我正在尝试将列添加到另一个文件的一个文件中。

离。

Week,Sales Depot,Sales Channel,Route,Client,Product,Units Sold,Sales,Units Returned,Returns,Adjusted Demand
3,1110,7,3301,15766,1212,3,25.14,0,0,3
3,1110,7,3301,15766,1216,4,33.52,0,0,4

结合

Units_cat
0
1

这样

Week,Sales Depot,Sales Channel,Route,Client,Product,Units Sold,Units_cat,Sales,Units Returned,Returns,Adjusted Demand
3,1110,7,3301,15766,1212,3,0,25.14,0,0,3
3,1110,7,3301,15766,1216,4,1,33.52,0,0,4

我一直在使用pandas读入并输出.csv文件,但我遇到的问题是程序不断崩溃,因为创建DataFrame会重载我的内存。我试过从Python应用csv库,但我不确定如何以我想要的方式合并文件(不仅仅是追加)。

任何人都知道一种更节省内存的方法来组合这些文件吗?

1 个答案:

答案 0 :(得分:4)

这样的事可能适合你:

使用csv.DictReader()

import csv
from itertools import izip

with open('file1.csv') as file1:
    with open('file2.csv') as file2:
        with open('result.csv', 'w') as result:
            file1 = csv.DictReader(file1)
            file2 = csv.DictReader(file2)

            # Get the field order correct here:
            fieldnames = file1.fieldnames
            index = fieldnames.index('Units Sold')+1
            fieldnames = fieldnames[:index] + file2.fieldnames + fieldnames[index:]

            result = csv.DictWriter(result, fieldnames)

            def dict_merge(a,b):
                a.update(b)
                return a
            result.writeheader()
            result.writerows(dict_merge(a,b) for a,b in izip(file1, file2))

使用csv.reader()

import csv
from itertools import izip

with open('file1.csv') as file1:
    with open('file2.csv') as file2:
        with open('result.csv', 'w') as result:
            file1 = csv.reader(file1)
            file2 = csv.reader(file2)
            result = csv.writer(result)

            result.writerows(a[:7] + b + a[7:] for a,b in izip(file1, file2))

注意:

  • 这适用于Python2。您可以在Python3中使用普通的zip()函数。如果这两个文件的长度不同,请考虑itertools.izip_longest()

  • 内存效率来自于将生成器表达式传递给.writerows()而不是列表。这样,在任何时刻都只考虑当前行,而不是整个文件。如果生成器表达式不合适,您将从for循环中获得相同的好处:for a,b in izip(...): result.writerow(...)

  • 从Python3.5开始不需要dict_merge函数。在足够新的蟒蛇中,试试result.writerows({**a,**b} for a,b in zip(file1, file2))(见this explanation)。