2009-10-07 33 views
11

Tôi có một loạt tệp văn bản lớn (tối đa 1 gig) là đầu ra từ thử nghiệm cần được phân tích bằng Python. Họ sẽ được nạp tốt nhất vào một mảng NumPy 2D, trong đó trình bày những câu hỏi đầu tiên:Tăng dần mảng xây dựng và đo mức sử dụng bộ nhớ

  • Là số hàng không rõ ở phần đầu của tải, làm thế nào có thể một mảng NumPy rất lớn được xây dựng một cách hiệu quả nhất, hàng này đến hàng kia?

Chỉ cần thêm hàng vào mảng sẽ không hiệu quả trong điều kiện bộ nhớ, vì hai mảng lớn sẽ cùng tồn tại trong giây lát. Vấn đề tương tự dường như sẽ xảy ra nếu bạn sử dụng numpy.append. Các chức năng stack là đầy hứa hẹn, nhưng lý tưởng là tôi muốn phát triển mảng tại chỗ.

Điều này dẫn đến câu hỏi thứ hai:

  • cách tốt nhất để quan sát việc sử dụng bộ nhớ của một chương trình Python mà rất nhiều sử dụng mảng NumPy là gì?

Để nghiên cứu vấn đề trên, tôi đã sử dụng các công cụ định dạng bộ nhớ thông thường - heapy và pympler - nhưng chỉ nhận được kích thước của các đối tượng mảng ngoài (80 byte) chứ không phải dữ liệu mà chúng chứa. Ngoài việc đo lường thô bao nhiêu bộ nhớ mà quá trình Python đang sử dụng, làm cách nào tôi có thể nhận được kích thước "đầy đủ" của các mảng khi chúng phát triển?

Chi tiết địa phương: OSX 10.6, Python 2.6, nhưng các giải pháp chung đều được chào đón.

Trả lời

7

Không có cách nào để đảm bảo bạn có thể phát triển mảng tại chỗ ngoài việc tạo mảng trống (numpy.empty) có kích thước tối đa có thể và sau đó sử dụng chế độ xem đó ở cuối. Bạn không thể bắt đầu nhỏ bởi vì không có gì đảm bảo rằng bạn có thể mở rộng bộ nhớ bất kỳ bản đồ nào mà không có một số dữ liệu khác. (Và tất cả điều này là mức thấp hơn nhiều so với python cho phép bạn nhận được từ bên trong thông dịch viên.)

Đặt cược tốt nhất của bạn có lẽ là numpy.fromiter. Nhìn vào nguồn, khi số lượng mục tăng lên, mảng được mở rộng thêm một ít hơn 50% mỗi lần. Nếu bạn có thể dễ dàng nhận được số hàng (nói từ đếm các dòng), bạn thậm chí có thể vượt qua nó một số.

1

Tùy chọn có thể là thực hiện một lần vượt qua tệp trước để đếm số hàng, mà không cần tải chúng.

Các tùy chọn khác là để tăng gấp đôi kích thước bảng của bạn mỗi lần, trong đó có hai lợi ích:

  1. Bạn sẽ chỉ tái alloc nhớ log (n) lần trong đó n là số hàng.
  2. Bạn chỉ cần ram nhiều hơn 50% so với kích thước bảng lớn nhất của bạn

Nếu bạn có những tuyến đường năng động, bạn có thể đo chiều dài của hàng đầu tiên trong byte, sau đó đoán số hàng bằng cách tính toán (num byte trong tệp/num byte trong hàng đầu tiên). Bắt đầu với một bảng có kích thước này.

+0

Cảm ơn tất cả. Với kích thước của tập tin, tôi đã miễn cưỡng thực hiện một bước đầu tiên chỉ để đếm dòng, nhưng nó có vẻ là cách dễ nhất và hiệu quả nhất để giải quyết vấn đề bộ nhớ. –

+1

Tôi đã có một đồng nghiệp hỏi một câu hỏi tương tự gần đây, và tôi đã đưa ra một khả năng khác có thể cứu bạn khỏi lần đầu tiên. Nếu bạn biết kích thước gần đúng của một "phần tử" trong tệp, bạn có thể chia nó thành kích thước tệp. Thêm một số đệm cho an toàn, và sau đó bạn có thể ghi vào toàn bộ bộ nhớ. Để ẩn thêm, chưa được khởi tạo, bạn có thể sử dụng chế độ xem chỉ các phần tử có dữ liệu. Bạn sẽ cần phải chắc chắn rằng bạn không đi qua. Nó không hoàn hảo, nhưng nếu tập tin của bạn đọc chậm, và dữ liệu của bạn được đặt ra một cách nhất quán, nó có thể hoạt động. – AFoglia

2

Bạn đã thử sử dụng tệp memmap chưa? Bạn có thể lặp qua tệp đầu vào của bạn (theo khối nếu có thể) và chuyển đổi dữ liệu đến và chèn chúng dưới dạng hàng vào mảng numpy được ánh xạ bộ nhớ. Nhược điểm là phát sinh thêm đĩa i/o trong trường hợp không đủ bộ nhớ chính và phân trang từ trao đổi trở nên cần thiết.

Xem: http://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

Một giải pháp thay thế khác là PyTables. Bạn sẽ cần phải xây dựng một số bảng giống như sql đặc biệt, nhưng nó khá đơn giản. Trong thực tế, nó cung cấp sự bền vững đĩa trong suốt (serialization tự động) và tổ chức phân cấp cho dữ liệu của bạn. Nó cũng giới hạn số lượng bộ nhớ chính được sử dụng.

Xem: www.pytables.org/moin/HowToUse

Chúc bạn may mắn!

0

Vấn đề cơ bản là tệp văn bản. Khi dữ liệu đầu vào của bạn được lưu trữ trong một nâng cao hơn từ, các vấn đề như vậy có thể tránh được. Lấy ví dụ một cái nhìn tại h5py project. Thật khó để chuyển đổi dữ liệu của bạn thành tệp HDF5 đầu tiên và sau đó chạy các tập lệnh phân tích trên các tệp HDF5.

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