2009-06-28 63 views
73

NumPy是一個非常有用的庫,使用它我發現它能夠容易地處理相當大(10000 x 10000)的矩陣,但開始與任何大得多的矩陣(試圖創建一個50000 x 50000的矩陣失敗)。顯然,這是因爲大量的內存需求。非常大的矩陣使用Python和NumPy

有沒有一種方法可以在NumPy(比如100萬)中以某種方式生成巨大的矩陣(沒有幾兆字節的RAM)?

+16

什麼是你(從創建它們分開),試圖與他們做什麼? – Rook 2009-06-28 03:13:57

回答

1

通常當我們處理大矩陣時,我們將它們實現爲Sparse Matrices

我不知道numpy是否支持稀疏矩陣,但是我找到了this

1

據我所知numpy,不,但我可能是錯的。

我可以爲您提供這種替代解決方案:在磁盤上寫入矩陣並以大塊訪問它。我建議你HDF5文件格式。如果您需要透明地使用它,則可以重新實現ndarray接口,將磁盤存儲的矩陣分頁到內存中。如果修改數據以將其同步到磁盤上,請小心。

+0

如果我想通過57600訪問57600的整個矩陣,該怎麼辦? – user3515225 2016-12-14 09:25:47

29

您應該能夠使用numpy.memmap來映射磁盤上的文件。使用更新的python和64位機器,您應該擁有必要的地址空間,而無需將所有內容加載到內存中。操作系統應該只處理內存中的部分文件。

+10

你能提供一個如何使用它來做一些不適合內存的例子嗎? – endolith 2013-10-31 21:25:06

24

要處理稀疏矩陣,您需要位於numpy之上的scipy程序包 - 有關scipy爲您提供的稀疏矩陣選項的更多詳細信息,請參見here

4

你問如何處理沒有TB的RAM的2,500,000,000個元素矩陣?

處理20億個沒有80億字節RAM的項目的方法是不把矩陣保留在內存中。

這意味着更復雜的算法可以將其從文件系統中分塊取出。

+6

不正確。如果元素的99.99%(對於一個實際的例子)是零,那麼矩陣的所有數據都可以保存在內存中。當你可以爲那些存在的條目存儲`(行,列,值)`列表時,不需要每4個字節用完。 – 2011-10-19 16:34:05

+3

@EricWilson:在問題中,它表明矩陣是稀疏的?我完全錯過了。你能提供報價嗎? – 2011-10-19 18:45:20

51

numpy.array s是爲了生活在記憶中。如果你想使用大於RAM的矩陣,你必須解決這個問題。至少有兩種方法可以遵循:

  1. 嘗試更有效的矩陣表示,它利用你的矩陣有任何特殊的結構。例如,正如其他人已經指出的那樣,稀疏矩陣(具有很多零的矩陣)有效的數據結構,如scipy.sparse.csc_matrix
  2. 修改您的算法以在子表中工作。您只能從磁盤讀取當前正在計算中使用的矩陣塊。設計用於在羣集上運行的算法通常以塊爲單位進行工作,因爲數據分散在不同的計算機上,並且僅在需要時傳遞。例如,the Fox algorithm for matrix multiplication (PDF file)
+4

3-大數據範例的步驟和研究解決方案,如MapReduce – Medeiros 2013-07-05 02:23:01

+0

對於數字2,您如何決定讓您的塊有多大?有沒有一種方法來衡量可用內存的數量和大小的基礎上呢? – endolith 2015-01-17 15:48:04

11

Stefano Borini的post讓我看看這種事情已經有多遠了。

This is it.它似乎基本上做你想要的。HDF5將允許您存儲非常大的數據集,然後以與NumPy相同的方式訪問和使用它們。

84

PyTables和NumPy是要走的路。

PyTables將以HDF格式將數據存儲在磁盤上,並具有可選壓縮功能。我的數據集經常得到10倍壓縮,這在處理數十或數百萬行時非常方便。它也非常快;我5歲的筆記本電腦可以通過執行類似SQL的GROUP BY聚合以1,000,000行/秒進行數據處理。對於基於Python的解決方案來說不錯!

訪問數據爲NumPy的recarray又是那樣簡單:

data = table[row_from:row_to] 

的HDF庫需要的讀取數據的相關塊,並轉換爲NumPy的照顧。

5

確保您使用的是64位操作系統和64位版本的Python/NumPy。請注意,在32位體系結構中,您通常可以解決3GB的內存問題(丟失內存映射I/O大約1GB等)。

由於64位和東西數組大於可用RAM,所以您可以使用虛擬內存,但如果必須交換,速度會變慢。此外,內存映射(請參閱numpy.memmap)是一種處理磁盤上大文件而不將它們加載到內存中的方式,但同樣需要有64位地址空間才能使用,因此非常有用。 PyTables也會爲你做大部分工作。

2

有時候一個簡單的解決方案是爲您的矩陣項目使用自定義類型。根據您需要的數字範圍,您可以使用手冊dtype,特別是您的物品更小。因爲Numpy在默認情況下考慮了對象的最大類型,所以在很多情況下這可能是一個有用的想法。這裏有一個例子:

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 

的和自定義類型:

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