2016-08-12 34 views
1

我需要在NumPy數組中寫入大量的數字 - 數字對。由於很多這樣的對具有第二個值0,我想到了類似於字典的東西。問題是我已經閱讀了關於結構化數組的NumPy文檔,並且似乎像構建頁面上的字典那樣的字典只能使用字符串作爲關鍵字。如何用NumPy數組實現字典?

除此之外,我需要插入和搜索具有日誌(N)的複雜性。我想用常規的NumPy數組作爲存儲來製作自己的紅黑樹結構,但我相當確定有一個更簡單的方法可以解決這個問題。

語言是Python 2.7.12。

+0

爲什麼你需要專門使用NumPy數組? –

+0

@David Z因爲我使用的數據量太多而無法存儲在RAM上。這就是爲什麼我需要給它另一種數據類型(這個[link](https://pypi.python.org/pypi/wendelin.core)),它支持直接寫入硬盤驅動器的數據庫。那東西基本上是一個NumPy陣列,能夠在需要時寫入硬盤... – Ilman

+0

啊,這是有用的信息(包括在問題中)。如果有一個使這項任務更容易的話,它還可以選擇使用不同的大容量存儲庫。 –

回答

0

所以,你有一個(N,2)陣列,並在x[:,1]許多值爲0

什麼您insertion意思?向數組添加一個值使其成爲(N+1,2)?或者只是將x[i,:]更改爲新的東西?

那麼搜索呢? numpy數組非常適合查找第i個值,x[i,:],但找到與z匹配的值不太好。 python numpy filter two dimentional array by condition

scipy.sparse實現了各種形式的稀疏矩陣,如果少於十分之一的可能值非零,這些稀疏矩陣是有用的。一種格式是dok,一個密鑰字典。它實際上是一個dict子類,而鍵是一個2d索引元組(i,j)。其他格式將它們的值存儲爲數組,例如。行,列和數據。

structured arrays是指具有適度數量的命名字段的情況,並且每個字段可以容納不同類型的數據。但我認爲將(N,2)陣列變成帶有2個字段的(N,)陣列是沒有用的。

================

您的意見建議你不熟悉numpy陣列是如何存儲或訪問。

陣列由一個扁平1D data buffer(只是一個c陣列的字節)的,和屬性等shapestridesitemsizedtype。我們假設這是np.arange(100)

In [1324]: np.arange(100).__array_interface__ 
Out[1324]: 
{'data': (163329128, False), 
'descr': [('', '<i4')], 
'shape': (100,), 
'strides': (4,) 
'typestr': '<i4', 
'version': 3} 

所以,如果我要求x[50],它計算的進步,4 bypes /元件,* 50個元素= 200個字節,並詢問,在c代碼在163329128+200的4個字節,並且將它們作爲一個整數(實際上np.int32類型的對象)。

對於結構化數組,descr類型和每個元素的字節數將會更大,但訪問權限是相同的。對於一個二維數組,它將採用這個形狀並且考慮元組來尋找合適的索引。 (N,2)整數數組的步幅爲(8,4)。因此訪問x[10,1]元素的偏移量爲10*8 + 1*4 = 84。並訪問x[:,1]i*8 for i in range...抵消。

但在任何情況下,它都依賴於以矩形可預測模式排列的值。關於numpy數據結構沒有什麼特別之處。它們相對較快,因爲許多操作都是以編譯代碼編碼的。

對數組進行排序,按值訪問項目以及重新排列元素都是可能的,但這不是強項。通常這些動作會產生一個新的數組,其中的值會以某種新的模式從舊到新複製。

只有幾個內建numpy數組子類,主要有np.matrixnp.masked_array,它們不擴展訪問方法。子類化並不像普通的Python類那樣容易,因爲它具有一些自己編譯的代碼。子類必須有一個__new__方法,而不是常規的__init__

有Python模塊維護排序列表,bisectheapq。但我不明白他們將如何幫助你處理大量的外存問題。

+0

你可以說我想要一個按其第一個元素排序的(N,2)數組,以便它具有複雜度O(logN)的插入和搜索。通過插入,我的意思是向數組中添加一個新元素,以保持它的排序狀態。通過搜索我的意思是找到索引,並因此找到元素的第二個值,給定它的第一個值。我知道這是可能的,因爲它是[紅黑樹](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree)所做的,這就是Python字典的工作原理。我問是否有這些屬性的numpy.array的內置子類型,因爲它具有索引... – Ilman

+0

由[NumPy的結構化數組頁面]中所述的元素(http://docs.scipy.org/ doc/numpy/user/basics.rec.html)(指定名稱而不是索引部分)。另外,我僅限於NumPy數組,因此沒有scipy或其他庫... – Ilman

+0

我已經展開了如何存儲和訪問numpy數組。 – hpaulj

0

詞典的最基本形式是名爲HashMap的結構。實現一個hashmap依賴於把你的密鑰變成一個可以快速查找的值。一個病理學示例將使用int s作爲關鍵字:關鍵字1的值將進入array[1],關鍵字2的值將進入array[2],該哈希函數僅僅是標識函數。你可以很容易地實現使用numpy數組。

如果您想使用其他類型,只需編寫一個很好的散列函數來將這些鍵轉換爲您的數組中的唯一索引。例如,如果你知道你有一個(int, int)元組,並且第一個值永遠不會超過100,那麼你可以做100*key[1] + key[0]

你的散列函數的實現是什麼會造成或破壞你的字典替換。

+0

是的,我明白了,我可以輕鬆構建我的數組,以便找到值的位置很快,但插入是問題。如果我想保持數組的排序,在插入之後,我需要將每個大於插入的元素移動到右邊,這樣有效地使插入的複雜度爲O(n)。我需要使用紅黑樹([link](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree))來實現O(logN)的複雜性,而不需要編寫它我自己... – Ilman