2013-02-26 42 views
9

Tôi muốn đọc một tệp văn bản lớn chứa danh sách các danh sách các số nguyên. Bây giờ tôi đang làm như sau:Cách nhanh nhất để đọc đầu vào bằng Python

G = [] 
with open("test.txt", 'r') as f: 
    for line in f: 
     G.append(list(map(int,line.split()))) 

Tuy nhiên, phải mất khoảng 17 giây (qua thời gian). Có cách nào để giảm thời gian này không? Có lẽ, có một cách không sử dụng bản đồ.

+0

Thử danh sách hiểu. –

+4

Có lý do gì để không sử dụng 'numpy' ở đây không? – DSM

+3

Xác định "rất lớn". Ngoài ra, mỗi dòng có cùng số nguyên không? –

Trả lời

0

Việc tăng tốc dễ nhất là nên đi cho PyPy http://pypy.org/

Vấn đề cạnh KHÔNG đọc các tập tin ở tất cả (nếu có thể). Thay vào đó, xử lý nó như một luồng.

0

Việc hiểu danh sách thường nhanh hơn.

G = [[int(item) item in line.split()] for line in f] 

Ngoài ra, hãy thử PyPy và Cython và NumPy

+0

'G = [map (int, line.split()) cho dòng trong f]' là nhanh hơn. –

+0

@StevenRumbalski Dòng này tạo ra các đối tượng bản đồ: '[<đối tượng bản đồ tại 0x0000000002D28898>, <đối tượng bản đồ tại 0x0000000002D28908>, <đối tượng bản đồ tại 0x0000000002D289B0> ...'. Nhưng dòng @forivall hoạt động. –

+0

@BranAlgue. Aha! Bạn đang sử dụng Python 3. Vì vậy, hãy thay đổi thành 'G = [list (map (int, line.split())) cho dòng trong f]'. Nó vẫn nhanh hơn so với danh sách lồng nhau. –

0

Bạn cũng có thể thử để đưa dữ liệu vào một cơ sở dữ liệu thông qua số lượng lớn chèn, sau đó xử lý hồ sơ của bạn với các hoạt động thiết lập. Tùy thuộc vào những gì bạn phải làm, điều đó có thể nhanh hơn, vì phần mềm chèn hàng loạt được tối ưu hóa cho loại tác vụ này.

1

Như một quy tắc chung về ngón tay cái (cho bất kỳ ngôn ngữ nào), sử dụng read() để đọc toàn bộ tệp sẽ nhanh hơn đọc từng dòng một. Nếu bạn không bị ràng buộc bởi bộ nhớ, hãy đọc toàn bộ tập tin cùng một lúc và sau đó chia nhỏ dữ liệu trên dòng mới, sau đó lặp qua danh sách các dòng.

22

numpy có các chức năng loadtxtgenfromtxt, nhưng không phải là đặc biệt nhanh. Một trong những trình đọc văn bản nhanh nhất có sẵn trong một thư viện được phân phối rộng rãi là hàm read_csv trong pandas (http://pandas.pydata.org/). Trên máy tính của tôi, đọc 5 triệu dòng chứa hai số nguyên trên mỗi dòng mất khoảng 46 giây với numpy.loadtxt, 26 giây với numpy.genfromtxt và nhỏ hơn 1 giây với pandas.read_csv.

Đây là phiên hiển thị kết quả. (Đây là trên Linux, Ubuntu 12.04 64 bit. Bạn không thể nhìn thấy nó ở đây, nhưng sau mỗi lần đọc các tập tin, bộ nhớ cache đĩa đã được xóa bằng cách chạy sync; echo 3 > /proc/sys/vm/drop_caches trong một vỏ riêng biệt.)

In [1]: import pandas as pd 

In [2]: %timeit -n1 -r1 loadtxt('junk.dat') 
1 loops, best of 1: 46.4 s per loop 

In [3]: %timeit -n1 -r1 genfromtxt('junk.dat') 
1 loops, best of 1: 26 s per loop 

In [4]: %timeit -n1 -r1 pd.read_csv('junk.dat', sep=' ', header=None) 
1 loops, best of 1: 1.12 s per loop 
+0

+1, không thấy câu trả lời của bạn trong khi tôi đang chuẩn bị. Tôi chỉ đánh giá phiên bản của OP quá, mất khoảng 16s trên máy tính của tôi. Tôi cũng lưu ý rằng 'loadtxt' là chậm. Tôi không chắc chắn lý do tại sao, tôi hy vọng nó sẽ nhanh hơn (và nó phải nhanh hơn 'genfromtxt'. Bạn cũng sử dụng numpy 1.7? – bmu

+0

@bmu: Có, tôi đã sử dụng số mũ 1.7. –

+2

Tôi đã mở một vấn đề gumpy: https://github.com/numpy/numpy/issues/3019 Tôi không thể tưởng tượng được, rằng nó là bình thường mà 'loadtxt' quá chậm – bmu

5

pandas mà được dựa trên numpyC dựa file parser mà là rất nhanh:

# generate some integer data (5 M rows, two cols) and write it to file 
In [24]: data = np.random.randint(1000, size=(5 * 10**6, 2)) 

In [25]: np.savetxt('testfile.txt', data, delimiter=' ', fmt='%d') 

# your way 
In [26]: def your_way(filename): 
    ...:  G = [] 
    ...:  with open(filename, 'r') as f: 
    ...:   for line in f: 
    ...:    G.append(list(map(int, line.split(',')))) 
    ...:  return G   
    ...: 

In [26]: %timeit your_way('testfile.txt', ' ') 
1 loops, best of 3: 16.2 s per loop 

In [27]: %timeit pd.read_csv('testfile.txt', delimiter=' ', dtype=int) 
1 loops, best of 3: 1.57 s per loop 

vì vậy pandas.read_csv mất khoảng một nửa để đọc dữ liệu của bạn và nhanh hơn so với phương pháp của bạn khoảng 10 lần.

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