Câu hỏi Ma trận rất lớn sử dụng Python và NumPy


NumPy là một thư viện cực kỳ hữu ích, và từ việc sử dụng nó, tôi thấy rằng nó có khả năng xử lý các ma trận khá lớn (10000 x 10000) một cách dễ dàng, nhưng bắt đầu đấu tranh với bất kỳ thứ gì lớn hơn (cố gắng tạo ma trận 50000 x 50000 không thành công ). Rõ ràng, điều này là do các yêu cầu bộ nhớ lớn.

Có cách nào để tạo ra ma trận lớn nguyên bản trong NumPy (nói 1 triệu 1 triệu) theo cách nào đó (không có nhiều terrabyte RAM)?


76
2018-06-28 00:32


gốc


Bạn đang cố gắng làm gì với họ (ngoài việc tạo ra chúng)? - Rook


Các câu trả lời:


PyTables và NumPy là con đường để đi.

PyTables sẽ lưu trữ dữ liệu trên đĩa ở định dạng HDF, với nén tùy chọn. Bộ dữ liệu của tôi thường nhận được nén 10x, rất tiện lợi khi xử lý hàng chục hoặc hàng trăm triệu hàng. Nó cũng rất nhanh; máy tính xách tay 5 năm tuổi của tôi có thể khủng hoảng thông qua dữ liệu thực hiện tổng hợp GROUP BY giống SQL ở mức 1.000.000 hàng / giây. Không tệ đối với một giải pháp dựa trên Python!

Việc truy cập dữ liệu dưới dạng một lần lặp lại NumPy cũng đơn giản như sau:

data = table[row_from:row_to]

Thư viện HDF chăm sóc đọc trong các khối dữ liệu có liên quan và chuyển đổi thành NumPy.


84
2018-06-30 09:11



Hãy cẩn thận để hiển thị một ví dụ mã nhanh về cách tiếp cận này? - Ivan
Vì vậy, bạn vẫn phải tự mình chia nhỏ dữ liệu thành các phần để xử lý? Nó chỉ là một cách để đơn giản hóa việc chuyển đổi đến và từ các tập tin đĩa? - endolith
Bất kỳ cơ hội nào bạn có thể mở rộng câu trả lời của mình bằng một chút rõ ràng hơn và một số ví dụ? - Adam B


numpy.arrays có nghĩa là sống trong ký ức. Nếu bạn muốn làm việc với ma trận lớn hơn RAM của bạn, bạn phải làm việc xung quanh đó. Có ít nhất hai phương pháp bạn có thể làm theo:

  1. Hãy thử một biểu diễn ma trận hiệu quả hơn khai thác bất kỳ cấu trúc đặc biệt nào mà ma trận của bạn có. Ví dụ, như những người khác đã chỉ ra, có những cấu trúc dữ liệu hiệu quả cho các ma trận thưa thớt (ma trận với nhiều số không), như scipy.sparse.csc_matrix.
  2. Sửa đổi thuật toán của bạn để làm việc trên các ngôn ngữ phụ. Bạn có thể đọc từ đĩa chỉ các khối ma trận hiện đang được sử dụng trong tính toán. Các thuật toán được thiết kế để chạy trên các cụm thường hoạt động theo khối, vì dữ liệu được phân tán trên các máy tính khác nhau và chỉ được truyền khi cần. Ví dụ, thuật toán Fox cho phép nhân ma trận (tệp PDF).

53
2018-06-28 02:53



3- Bước vào mô hình Dữ liệu lớn và các giải pháp nghiên cứu như MapReduce - Medeiros
Đối với số 2, làm thế nào để bạn quyết định làm thế nào lớn để làm cho khối của bạn? Có cách nào để đo lường số lượng bộ nhớ miễn phí và kích thước khối của bạn dựa trên đó? - endolith


Bạn sẽ có thể sử dụng numpy.memmap để bộ nhớ ánh xạ một tệp trên đĩa. Với máy python và 64 bit mới hơn, bạn nên có không gian địa chỉ cần thiết, mà không cần tải mọi thứ vào bộ nhớ. Hệ điều hành nên xử lý chỉ giữ một phần của tập tin trong bộ nhớ.


29
2018-06-28 01:46



Bạn có thể cung cấp một ví dụ về cách sử dụng nó để làm một cái gì đó mà không thể phù hợp trong bộ nhớ? - endolith


Để xử lý các ma trận thưa thớt, bạn cần scipy gói nằm trên đầu trang numpy -- xem đây để biết thêm chi tiết về các tùy chọn ma trận thưa thớt scipy mang đến cho bạn.


24
2018-06-28 02:23





Stefano Borini's bài đăng khiến tôi nhìn vào khoảng cách như thế này.

Đây chính là nó.  Nó dường như làm cơ bản những gì bạn muốn. HDF5 sẽ cho phép bạn lưu trữ các tập dữ liệu rất lớn, sau đó truy cập và sử dụng chúng theo cùng một cách mà NumPy thực hiện.


11
2018-06-28 02:54



Một lựa chọn tốt hơn có thể là PyTables. Đó là cấp độ cao hơn chức năng HDF5 lõi (H5Py là ít hơn so với API cấp thấp có thể truy cập từ Python). Ngoài ra, phiên bản 2.2 beta của tuần trước có các công cụ cho vấn đề này: pytables.org/moin/ReleaseNotes/Release_2.2b1 Đã thêm Expr, một lớp [có thể đánh giá các biểu thức (như '3 * a + 4 * b') hoạt động trên các mảng lớn tùy ý trong khi tối ưu hóa tài nguyên [...]. Nó tương tự như gói Numexpr, nhưng ngoài các đối tượng NumPy, nó cũng chấp nhận các mảng đồng nhất dựa trên đĩa, như các đối tượng Array, CArray, EArray và Column PyTables. - AFoglia


Đảm bảo bạn đang sử dụng hệ điều hành 64 bit và phiên bản Python / NumPy 64 bit. Lưu ý rằng trên kiến ​​trúc 32 bit, bạn có thể giải quyết 3GB bộ nhớ thông thường (với khoảng 1GB bị mất đến bộ nhớ ánh xạ I / O và như vậy).

Với mảng 64 bit và nhiều thứ hơn RAM có sẵn, bạn có thể lấy đi bộ nhớ ảo, mặc dù mọi thứ sẽ chậm hơn nếu bạn phải trao đổi. Ngoài ra, các bản đồ bộ nhớ (xem numpy.memmap) là một cách để làm việc với các tệp lớn trên đĩa mà không cần nạp chúng vào bộ nhớ, nhưng một lần nữa, bạn cần có một không gian địa chỉ 64 bit để làm việc với điều này. PyTables sẽ làm hầu hết điều này cho bạn.


5
2017-08-19 00:27





Đó là một chút alpha, nhưng http://blaze.pydata.org/ dường như đang giải quyết vấn đề này.


5
2018-02-05 00:58





Bạn đang hỏi làm thế nào để xử lý một ma trận phần tử 2,500.000.000 mà không có terabyte RAM?

Cách xử lý 2 tỷ mục không có 8 tỷ byte RAM là do không giữ ma trận trong bộ nhớ.

Điều đó có nghĩa là các thuật toán phức tạp hơn nhiều để lấy nó từ hệ thống tệp theo từng phần.


4
2018-06-28 02:32



Không đúng. Nếu 99,99% (đối với một ví dụ thực tế) của các phần tử bằng không, thì tất cả dữ liệu của ma trận có thể được giữ trong bộ nhớ. Không cần sử dụng hết 4 byte cho mỗi số không, khi bạn chỉ có thể lưu trữ danh sách (row, column, value) cho những mục có tồn tại. - Eric Wilson
@EricWilson: Ở đâu trong câu hỏi đã làm nó đề nghị ma trận là thưa thớt? Tôi hoàn toàn bỏ lỡ điều đó. Bạn có thể cung cấp báo giá? - S.Lott


Đôi khi một giải pháp đơn giản là sử dụng một loại tùy chỉnh cho các mục ma trận của bạn. Dựa trên phạm vi số bạn cần, bạn có thể sử dụng hướng dẫn dtype và đặc biệt nhỏ hơn cho các mặt hàng của bạn. Bởi vì Numpy coi loại lớn nhất cho đối tượng theo mặc định, đây có thể là một ý tưởng hữu ích trong nhiều trường hợp. Đây là một ví dụ:

In [70]: a = np.arange(5)

In [71]: a[0].dtype
Out[71]: dtype('int64')

In [72]: a.nbytes
Out[72]: 40

In [73]: a = np.arange(0, 2, 0.5)

In [74]: a[0].dtype
Out[74]: dtype('float64')

In [75]: a.nbytes
Out[75]: 32

Và với loại tùy chỉnh:

In [80]: a = np.arange(5, dtype=np.int8)

In [81]: a.nbytes
Out[81]: 5

In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)

In [78]: a.nbytes
Out[78]: 8

3
2017-10-03 22:09





Thông thường khi chúng ta đối phó với ma trận lớn, chúng ta thực hiện chúng như Ma trận thưa thớt.

Tôi không biết nếu hỗ trợ một cách uể oải ma trận thưa thớt nhưng tôi tìm thấy điều này thay thế.


1
2018-06-28 00:45





Theo như tôi biết về numpy, không, nhưng tôi có thể sai.

Tôi có thể đề xuất cho bạn giải pháp thay thế này: viết ma trận trên đĩa và truy cập nó theo khối. Tôi đề nghị bạn định dạng tệp HDF5. Nếu bạn cần nó một cách minh bạch, bạn có thể triển khai lại giao diện ndarray để phân trang ma trận được lưu trữ trên đĩa của bạn thành bộ nhớ. Hãy cẩn thận nếu bạn sửa đổi dữ liệu để đồng bộ hóa chúng trở lại trên đĩa.


1
2018-06-28 00:46



Điều gì sẽ xảy ra nếu tôi muốn truy cập toàn bộ ma trận 57600 57600? - user3515225