2012-11-15 21 views
6

Tôi khá mới với python và lập trình nói chung, nhưng tôi đang cố gắng chạy một "cửa sổ trượt" tính toán trên một tệp .txt được phân cách bằng tab chứa khoảng 7 triệu dòng với python . Những gì tôi có nghĩa là bằng cách trượt cửa sổ là nó sẽ chạy một tính toán trên nói 50.000 dòng, báo cáo số lượng và sau đó di chuyển lên nói 10.000 dòng và thực hiện các tính toán tương tự trên 50.000 dòng khác. Tôi có tính toán và "cửa sổ trượt" hoạt động chính xác và nó chạy tốt nếu tôi thử nghiệm nó trên một tập hợp nhỏ dữ liệu của tôi. Tuy nhiên, nếu tôi cố gắng chạy chương trình trên toàn bộ dữ liệu của tôi, nó cực kỳ chậm (tôi đã chạy nó trong khoảng 40 giờ). Toán học khá đơn giản vì vậy tôi không nghĩ rằng nó nên được thực hiện trong thời gian dài.Xử lý tệp .txt lớn trong python hiệu quả

Cách tôi đang đọc tệp .txt của mình ngay bây giờ là với mô-đun csv.DictReader. Mã của tôi là như sau:

file1='/Users/Shared/SmallSetbee.txt' 
newfile=open(file1, 'rb') 
reader=csv.DictReader((line.replace('\0','') for line in newfile), delimiter="\t") 

Tôi tin rằng điều này đang thực hiện một cuốn từ điển trong số tất cả 7 triệu dòng cùng một lúc, mà tôi đang nghĩ có thể là lý do nó chậm lại rất nhiều cho các tập tin lớn hơn.

Vì tôi chỉ quan tâm đến việc tính toán theo "khối" hoặc "cửa sổ" dữ liệu cùng một lúc, có cách hiệu quả hơn để chỉ đọc trong các dòng được chỉ định tại một thời điểm, thực hiện phép tính và sau đó lặp lại một "chunk" hoặc "cửa sổ" được chỉ định mới của các dòng được chỉ định?

+1

Điều này không làm từ điển của tất cả các dòng cùng một lúc. Nó làm cho một từ điển cho mỗi dòng. Điều này có nghĩa là đoạn trích bạn đăng không phải là nguyên nhân gây ra tai họa hiệu suất của bạn. Có lẽ bạn có thể cho chúng tôi thấy một số mã nữa? –

+1

Tôi nghi ngờ rằng nếu bạn đang thực hiện các phép tính trên một lượng lớn dữ liệu giống bảng, bạn có thể muốn xem Pandas: http://pandas.pydata.org/pandas-docs/dev/io.html#iterating-through- Tất cả mọi thứ bạn đang cố gắng làm có thể đã được thực hiện trước 1000 lần tốt hơn. – Iguananaut

+0

Bạn sẽ chạy tính toán này trên 696 "cửa sổ". Mất bao lâu để một cửa sổ duy nhất trên một tệp dòng 50k? –

Trả lời

6

A collections.deque là bộ sưu tập các mặt hàng được sắp xếp có thể có kích thước tối đa. Khi bạn thêm một mục vào một đầu, một mục nằm ở đầu kia. Điều này có nghĩa rằng để lặp qua một "cửa sổ" trên csv của bạn, bạn chỉ cần tiếp tục thêm hàng vào deque và nó sẽ xử lý việc ném đi những cái đã hoàn thành rồi.

dq = collections.deque(maxlen=50000) 
with open(...) as csv_file: 
    reader = csv.DictReader((line.replace("\0", "") for line in csv_file), delimiter="\t") 

    # initial fill 
    for _ in range(50000): 
     dq.append(reader.next()) 

    # repeated compute 
    try: 
     while 1: 
      compute(dq) 
      for _ in range(10000): 
       dq.append(reader.next()) 
    except StopIteration: 
      compute(dq) 
+1

'try/except' nên gần gũi hơn với' reader.next() 'để tránh vô tình bắt 'StopIteration' từ' compute (dq) ' – jfs

3

Không sử dụng csv.DictReader, thay vào đó sử dụng csv.reader. Mất nhiều thời gian hơn để tạo một từ điển cho mỗi hàng so với việc tạo một danh sách cho mỗi hàng. Ngoài ra, nó là nhanh hơn để truy cập vào một danh sách của một chỉ số hơn là để truy cập vào một từ điển bằng một khóa.

Tôi lặp lại theo thời gian trên tệp csv 300.000 dòng 4 cột bằng cách sử dụng hai trình đọc csv. csv.DictReader mất dài hơn bảy lần so với csv.reader.

Kết hợp điều này với katrielalex's suggestion để sử dụng collections.deque và bạn sẽ thấy tăng tốc tốt đẹp.

Ngoài ra, profile mã của bạn để xác định nơi bạn dành phần lớn thời gian của mình.