如何根据第一列的内容拆分巨大的csv文件?

时间:2012-02-28 20:19:56

标签: python linux unix ubuntu

  • 我有一个250MB +巨大的csv文件要上传
  • 文件格式为group_id, application_id, reading,数据可能为
1, a1, 0.1
1, a1, 0.2
1, a1, 0.4
1, a1, 0.3
1, a1, 0.0
1, a1, 0.9
2, b1, 0.1
2, b1, 0.2
2, b1, 0.4
2, b1, 0.3
2, b1, 0.0
2, b1, 0.9
.....
n, x, 0.3(lets say)  
  • 我想根据group_id划分文件,因此输出应为n个文件n=group_id

输出

File 1

1, a1, 0.1
1, a1, 0.2
1, a1, 0.4
1, a1, 0.3
1, a1, 0.0
1, a1, 0.9

File2
2, b1, 0.1
2, b1, 0.2
2, b1, 0.4
2, b1, 0.3
2, b1, 0.0
2, b1, 0.9
.....

File n
n, x, 0.3(lets say)  

我该如何有效地做到这一点?

7 个答案:

答案 0 :(得分:17)

awk有能力:

 awk -F "," '{print $0 >> ("FILE" $1)}' HUGE.csv

答案 1 :(得分:8)

如果文件已按group_id排序,您可以执行以下操作:

import csv
from itertools import groupby

for key, rows in groupby(csv.reader(open("foo.csv")),
                         lambda row: row[0]):
    with open("%s.txt" % key, "w") as output:
        for row in rows:
            output.write(",".join(row) + "\n")

答案 2 :(得分:4)

Sed one-liner:

sed -e '/^1,/wFile1' -e '/^2,/wFile2' -e '/^3,/wFile3' ... OriginalFile 

唯一的缺点是您需要输入 n -e语句(由省略号表示,不应出现在最终版本中)。所以这个单行可能是一个很长的路线。

但好处是,它只会传递一个文件,不会进行排序,也不需要python。另外,它是一个令人毛骨悚然的衬垫!

答案 3 :(得分:2)

如果行按group_id排序,则itertools.groupby在此处有用。因为它是一个迭代器,所以你不必将整个文件加载到内存中;你仍然可以逐行编写每个文件。使用csv加载文件(如果您还不知道的话)。

答案 4 :(得分:1)

如果它们按组ID排序,您可以使用csv模块迭代文件中的行并输出它。您可以找到有关模块here的信息。

答案 5 :(得分:1)

怎么样:

  • 一次读取输入文件
  • split() ,上的每一行获取group_id
  • 对于您找到的每个新group_id,打开一个输出文件
    • 在找到它们时将每个groupid添加到set / dict中,以便您可以跟踪
  • 将该行写入相应的文件
  • 完成!

答案 6 :(得分:1)

这里有一些值得思考的食物:

import csv
from collections import namedtuple

csvfile = namedtuple('scvfile',('file','writer'))

class CSVFileCollections(object):

    def __init__(self,prefix,postfix):
        self.prefix = prefix
        self.files = {}

    def __getitem__(self,item):
        if item not in self.files:
            file = open(self.prefix+str(item)+self.postfix,'wb')
            writer = csv.writer(file,delimiter = ',', quotechar = "'",quoting=csv.QUOTE_MINIMAL)
            self.files[item] = csvfile(file,writer) 
        return self.files[item].writer

    def __enter__(self): pass

    def __exit__(self, exc_type, exc_value, traceback):
        for csvfile in self.files.values() : csvfile.file.close()


with open('huge.csv') as readFile, CSVFileCollections('output','.csv') as output:
    reader = csv.reader(readFile, delimiter=",", quotechar="'")
    for row in reader:
        writer = output[row[0]]
        writer.writerow(row)