2012-05-20 9 views
6

Tôi có khoảng 500 GB tệp văn bản được phân tách trong các tháng. Trong các tệp văn bản này, 43 dòng đầu tiên chỉ là thông tin kết nối (không cần thiết). 75 dòng tiếp theo là các bộ mô tả cho một quan sát. Tiếp theo là 4 dòng (không cần thiết) thì quan sát tiếp theo là 75 dòng.Cách nhanh nhất để nhập tệp văn bản 500GB chỉ lấy các phần muốn

Vấn đề là tất cả tôi muốn là những 75 dòng (mô tả là trong cùng một vị trí cho mỗi quan sát) được đặc trưng như thế này:

ID: 5523 
Date: 20052012 
Mixed: <Null> 
. 
. 

Và tôi muốn thay đổi nó sang định dạng csv 5523;20052012;;.. cho mỗi quan sát. Vì vậy, tôi kết thúc với các tập tin văn bản nhỏ hơn nhiều. Vì các bộ mô tả giống nhau, tôi sẽ biết vị trí đầu tiên là ID.

Khi tôi kết thúc với tệp văn bản, tôi sẽ mở phần tiếp theo và thêm nó (hoặc sẽ tạo tệp mới nhanh hơn?).

Những gì tôi đã làm là khá không hiệu quả Tôi đã mở tệp. Đang tải nó. Xóa các quan sát này theo từng dòng. Nếu nó lấy một chút công bằng với một mẫu thử thì rõ ràng đó không phải là phương pháp tốt nhất.

Mọi đề xuất sẽ tuyệt vời.

+1

có bất kỳ phần nào của tập tin của bạn cố định chiều dài? –

+0

Lưu ý.CSV sử dụng, không; –

+0

Có, do đó tên: [CSV, Giá trị được phân tách bằng dấu phẩy] (http://en.wikipedia.org/wiki/Comma-separated_values) – voithos

Trả lời

6

Bạn nói rằng bạn có "khoảng 500 GB tệp văn bản". Nếu tôi hiểu chính xác, bạn không có độ dài cố định cho mỗi quan sát (lưu ý, tôi không nói về số lượng dòng, ý tôi là tổng chiều dài tính theo byte, của tất cả các dòng để quan sát) . Điều này có nghĩa là bạn sẽ phải trải qua toàn bộ tệp vì bạn không thể biết chính xác vị trí của dòng mới.

Bây giờ, tùy thuộc vào mức độ lớn của từng tệp văn bản riêng lẻ, bạn có thể cần phải tìm câu trả lời khác. Nhưng nếu mỗi tập tin là đủ nhỏ (ít hơn 1 GB?), Bạn có thể sử dụng mô-đun linecache, xử lý tìm kiếm theo dòng cho bạn.

Bạn muốn sử dụng nó có lẽ như thế này:

import linecache 

filename = 'observations1.txt' 

# Start at 44th line 
curline = 44 
lines = [] 

# Keep looping until no return string is found 
# getline() never throws errors, but returns an empty string '' 
# if the line wasn't found (if the line was actually empty, it would have 
# returned the newline character '\n') 
while linecache.getline(filename, curline): 
    for i in xrange(75): 
     lines.append(linecache.getline(filename, curline).rstrip()) 
     curline += 1 

    # Perform work with the set of observation lines 
    add_to_observation_log(lines) 

    # Skip the unnecessary section and reset the lines list 
    curline += 4 
    lines = [] 

Tôi đã thử một bài kiểm tra điều này, và nó nhai qua một tập tin 23MB trong năm giây.

+0

Cảm ơn bạn đã hướng dẫn tôi đến mô-đun này. Dữ liệu là khoảng 1GB là một chút lớn hơn nhân dịp nhưng tôi nghĩ rằng điều này sẽ làm việc cho kích thước của nó. Lý do tôi cố gắng tránh xa việc sử dụng danh sách là tôi đã gặp vấn đề khi viết chúng. Làm việc từ mã của bạn Tôi đã nhanh chóng điều chỉnh nó cho mục đích sử dụng của tôi: – FancyDolphin

+0

trong khi linecache.getline (tên tệp, đường cong): cho i trong phạm vi (75): data_manipulated = linecache.getline (tên tệp, curline) .rstrip() datamanipulated2 = data_manipulated.split (":") datamanipulated2.pop (0) lines.append (datamanipulated2) curline + = 1 /* với open ('outputfile', "a") như f: ## f.write (lines)/* Điều này cho bạn một lỗi rằng đối tượng 'list' không có thuộc tính 'write' – FancyDolphin

+0

Vì vậy, tôi quyết định thông minh .... Và thử những điều sau đây: f = print (','. join (map (str, lines))) Sau đó, bạn sẽ có được lowing error TypeError: phải là str, không phải _io.TextIOWrapper Tôi cảm thấy như awnser là ery đơn giản nhưng tôi thiếu nó, bất cứ đề nghị? Cảm ơn một lần nữa cho mô-đun linecache. – FancyDolphin

2

opening the file. Loading it. Deleting these observations going line by line.

Bạn có ý gì khi "tải tệp"? Nếu bạn có nghĩa là đọc toàn bộ điều vào một chuỗi, sau đó có điều này sẽ hút. Cách tự nhiên để xử lý tệp là tận dụng lợi thế của thực tế là đối tượng tệp là một trình lặp trên các dòng của tệp:

for line in file: 
    if should_use(line): do_something_with(line) 
0

Bạn nên xem xét ghi thông tin bạn muốn lưu vào cơ sở dữ liệu. Trong python bạn có thể sử dụng sqlite3 được tích hợp sẵn. Thật dễ hiểu fom docs.

Bạn nói rằng bây giờ bạn chính xác các dòng trong mỗi tệp mà bạn muốn giữ lại. Vì vậy, bạn có thể thử một cái gì đó như thế này.

import csv 
    reader = csv.reader(open("afile.csv","rb"),delimiter="\t",quotechar='"') 
    info_to_keep = [] 
    obs = [] 
    for row in reader: 
     i+=1 
     if i<43: 
      continue 
     elif i-43 <79*(len(info_to_keep)+1)-4: 
      obs.append(row) 
     elif i-43 <79*(len(info_to_keep)+1): 
      continue 
     else: 
      info_to_keep.append(obs) 
      obs = [row] 

Bằng cách đó bạn có thể có một danh sách tên info_to_keep với mỗi mục có chứa một danh sách với 75 mục, mỗi có chứa có một danh sách với các lĩnh vực từ csv file