2012-02-28 29 views
9
  • Tôi có một 250MB + tập tin csv lớn để tải lên
  • định dạng tập tin là group_id, application_id, reading và dữ liệu có thể trông giống như
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) 
  • Tôi muốn chia file dựa trên group_id, do đó, đầu ra phải là n tệp nơi n=group_id

OutputCách tách tệp csv khổng lồ dựa trên nội dung của cột đầu tiên?

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) 

Tôi làm cách nào để thực hiện điều này một cách hiệu quả?

+0

Are các hàng được sắp xếp bởi 'group_id'? – senderle

+0

Dự kiến ​​rằng id nhóm đã được sắp xếp chưa? – aweis

Trả lời

7

Nếu tập tin đã được sắp xếp theo group_id, bạn có thể làm điều gì đó như:

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") 
+1

bạn có thể sử dụng 'operator.itemgetter (0)' thay vì lambda xấu xí –

+1

Có phải 'operator.itemgetter (0)' thực sự kém xấu hơn 'hàng lambda: hàng [0]'? –

+0

@StevenRumbalski: trong mọi trường hợp, nó nhanh hơn 'lambda'. Tôi bỏ nó ra vì tôi sợ nó có thể gây nhầm lẫn. –

1

Nếu chúng được sắp xếp theo id nhóm, bạn có thể sử dụng mô-đun csv để lặp qua các hàng trong tệp và xuất nó. Bạn có thể tìm thông tin về mô-đun here.

1

Làm thế nào về:

  • đọc tập tin đầu vào một dòng tại một thời điểm
  • split() mỗi dòng trên , để có được những group_id
  • Đối với mỗi GROUP_ID mới bạn tìm kiếm, mở một tập tin đầu ra
    • thêm từng nhóm vào tập hợp/dict khi bạn tìm thấy chúng để bạn có thể theo dõi
  • ghi dòng vào tệp thích hợp
  • Xong!
2

Nếu các hàng được sắp xếp theo group_id thì itertools.groupby sẽ hữu ích ở đây. Bởi vì nó là một iterator, bạn sẽ không phải tải toàn bộ tập tin vào bộ nhớ; bạn vẫn có thể viết từng dòng tệp theo từng dòng. Sử dụng csv để tải tệp (trong trường hợp bạn chưa biết về tệp đó).

1

Dưới đây một số thức ăn cho dù cho bạn:

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

Sed một liner:

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

Chỉ từ phía dưới là bạn cần phải đặt trong n-e báo cáo (được biểu thị bằng dấu chấm lửng, không nên xuất hiện trong phiên bản cuối cùng). Vì vậy, một lớp lót này có thể là một dòng khá dài.

Mặc dù vậy, các upsides chỉ cho phép một người vượt qua tệp, không có phân loại nào được giả định và không cần có python. Thêm vào đó, đó là một lớp lót kỳ quái!

13

awk có khả năng:

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

Ồ, vâng. Đó là tốt hơn so với cách của tôi. Mặc dù, bạn đang thiếu báo giá đơn đầu tiên trên lệnh đó. Và tôi nghĩ rằng mơ mộng muốn có '(" File "$ 1)'. – Mike

+0

Cảm ơn bạn đã chỉ mục này ra @Mike. –

+0

Tôi nhận được "awk: [ONE_OUTPUT_FILENAME] tạo quá nhiều tệp mở" khi sử dụng phương pháp này sau khi tạo 17 tệp đầu tiên. Thêm '; đóng ("FILE" $ 1) 'để lệnh awk giải quyết vấn đề đó. –

Các vấn đề liên quan