2011-12-09 20 views
6

Tôi đang xử lý dữ liệu lớn, vì vậy việc tìm kiếm một cách tốt để đọc dữ liệu thực sự quan trọng. Tôi chỉ hơi bối rối về các phương pháp đọc khác nhau.Các cách khác nhau để đọc dữ liệu lớn trong python

1.f=gzip.open(file,'r') 
     for line in f: 
      process line 
    #how can I process nth line? can I? 
2.f=gzip.open(file,'r').readlines() 
    #f is a list 
    f[10000] 
    #we can process nth line 

3.f=gzip.open(file,'r') 
    while True: 
     linelist=list(islice(f,4)) 

4.for line in fileinput.input(): 
    process line 

Sự khác nhau giữa 2 và 3 là gì? Tôi chỉ thấy việc sử dụng bộ nhớ của họ là như nhau. islice() cũng cần phải tải toàn bộ tập tin vào bộ nhớ (nhưng sau này chỉ mất chút thời gian). Và tôi nghe phương pháp thứ 4 là bộ nhớ ít tốn kém nhất, nó thực sự xử lý từng chút một, phải không? Đối với tệp có kích thước 10GB, bạn nên giới thiệu phương pháp đọc tệp nào? Bất kỳ suy nghĩ/thông tin được hoan nghênh. thx

chỉnh sửa: Tôi nghĩ rằng một trong những vấn đề của tôi là tôi cần phải chọn ra các dòng cụ thể ngẫu nhiên đôi khi. nói:

f1=open(inputfile1, 'r') 
while True: 
    line_group1 = list(islice(f1, 3)) 
    if not line_group1: 
     break 
    #then process specific lines say, the second line. 
    processed 2nd line 
    if (....): 
      LIST1.append(line_group1[0]) 
      LIST1.append(processed 2nd line) 
      LIST1.append(line_group1[2]) 

Và sau đó sth. như

with open(file,'r') as f, 
    for line in f: 
     # process line 

có thể không hoạt động, tôi có chính xác không?

+0

vì vậy, có yêu cầu phải có quyền truy cập dòng ngẫu nhiên vào tệp văn bản lớn không? –

+0

Vâng, thực sự không nhất thiết. Về cơ bản vẫn xử lý từng dòng một; hoặc N dòng như một nhóm. – user815408

Trả lời

4

Bạn quên -

with open(...) as f: 
    for line in f: 
     <do something with line> 

Các with xử lý tuyên bố mở và đóng tệp, bao gồm nếu ngoại lệ được nâng lên trong khối bên trong. Các for line in f xử lý đối tượng tập tin f như một iterable, tự động sử dụng bộ đệm IO và quản lý bộ nhớ, do đó bạn không phải lo lắng về các tệp lớn.

Cả hai 2,3 không được khuyến cáo cho các tệp lớn khi đọc & tải toàn bộ nội dung tệp trong bộ nhớ trước khi bắt đầu xử lý. Để đọc các tệp lớn, bạn cần tìm cách không đọc toàn bộ tệp trong một lần.

Nên có một - và tốt nhất là chỉ có một cách rõ ràng để thực hiện.

+0

Không thể +1 lần thứ hai sau khi chỉnh sửa cho báo giá ZEN ... Mặc dù đã thực hiện đạo đức! ;) – mac

+0

thx, nhưng bạn có thể xem bản chỉnh sửa của mình không? đôi khi tôi cần phải lấy dòng cụ thể (nói, dòng 10000). Sau đó làm thế nào tôi có thể làm gì? – user815408

+0

đơn giản, sau đó giữ một 'counter' mà về cơ bản là dòng num. Kiểm tra xem dòng 10000 của nó & làm xử lý đặc biệt của bạn. –

1

Bạn có thể sử dụng enumerate để có được một chỉ số như bạn lặp qua một cái gì đó:

for idx, line in enumerate(f): 
    # process line 

đơn giản và bộ nhớ hiệu quả. Bạn thực sự có thể sử dụng islice quá, và lặp trên nó mà không chuyển đổi vào một danh sách đầu tiên:

for line in islice(f,start,stop): 
    # process line 

cách tiếp cận Cả sẽ đọc toàn bộ tập tin vào bộ nhớ, cũng không tạo ra một danh sách trung gian.

Đối với fileinput, đây chỉ là lớp trợ giúp để lặp nhanh chóng trên đầu vào tiêu chuẩn hoặc danh sách tệp, không có lợi ích về bộ nhớ hiệu quả khi sử dụng nó.

Như Srikar chỉ ra, sử dụng câu lệnh with là cách ưa thích để mở/đóng tệp.

+0

với islice (f, 4), nếu tôi không tạo danh sách, thì làm sao tôi có thể chọn ra dòng đầu tiên, thứ hai, thứ ba và thứ tư? (như tôi làm trong bài viết) – user815408

+0

Chỉ cần lặp lại nó một cách bình thường, 'cho dòng trong islice (f, 4): dòng in' sẽ in các dòng 1,2,3,4. Nếu bạn muốn dòng 2 đến 5 bạn có thể sử dụng 'islice (2,6)' thay vào đó, v.v. – zeekay

0

bạn không biết có bao nhiêu dòng cho đến khi bạn đọc và đếm số lượng \ n trong đó. Trong 1, bạn có thể thêm một liệt kê để lấy số dòng.

0

Để đọc các dòng cụ thể trong các tệp lớn, bạn có thể sử dụng linecache library.

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