2016-04-25 47 views
6

我正在使用數組模塊來存儲大量數字(許多千兆字節)的無符號32位整數。 python使用8個字節,而不是每個元素使用4個字節,如array.itemsize所示,並由pympler驗證。我可以強制python數組元素具有特定的大小嗎?

例如:

>>> array("L", range(10)).itemsize 
8 

我有一個大數量的元素,所以我會從內的4個字節存儲它們受益。

numpy的會讓我的值存儲爲32位無符號整型:

>>> np.array(range(10), dtype = np.uint32).itemsize 
4 

但問題是,使用numpy的索引操作員的操作大約是慢一倍,所以支持不屬於矢量運算操作由numpy緩慢。 如:

python3 -m timeit -s "from array import array; a = array('L', range(1000))" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 51.4 usec per loop 

VS

python3 -m timeit -s "import numpy as np; a = np.array(range(1000), dtype = np.uint32)" "for i in range(len(a)): a[i]" 
10000 loops, best of 3: 90.4 usec per loop 

所以我被迫使用兩倍的內存,因爲我想,或者該程序將運行兩次,因爲我想慢。有沒有解決的辦法?我可以強制Python數組使用指定的itemsize嗎?

+0

https://bugs.python.org/issue26821 –

+0

這是一個虛假的二分法:你的程序可以使用更少的內存並且速度更快。雖然它與您是否可以在不同平臺上使用固定大小的'array'項目無關('array'可能使用平臺本機的C型大小)。這是一個單獨的問題:如何更快地製作特定的基於numpy的計算。 – jfs

回答

5

如果你要堅持使用arrayset the typecodeIunsigned int)而不是Lunsigned long):

>>> array.array("I", range(10)).itemsize 
4 

這就是說,如果沒有一種方法可以加速你的計算方式,而不是使用numpy失去的2倍以上,那麼我會感到非常驚訝。很難說,不知道你在用這些價值觀做什麼。

1

兩件事:使用numpy.arange()(內法)

並避免使用用於與numpy的語句(計算機速度的原因)。儘可能嘗試使用廣播技術。

獲取所有項目的更簡單的方法是使用.ravel()如果numpy數組的形狀阻礙。

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "for i in range(len(a)): a[i]" 

10000圈,最好的3:每圈106微秒

python3 -m timeit -s "import numpy as np; a = np.arange(1000), 
....... dtype = np.uint32)" "a.ravel()" 

百萬循環,最好的3:每圈0.218微秒

1

正如所看到的herearray.array是一箇舊的工具,沒有特別的興趣(據我所知)。

如果您有效率問題,numpy.arrayarray.array的最佳選擇,它提供了許多優化的矢量化工具。在這種情況下,32位運算往往比那些64bits的更快,即使是在64位系統:

import numpy as np 
In [528]: %timeit np.sum(a32) 
1000 loops, best of 3: 1.86 ms per loop 

In [529]: %timeit np.sum(a64) 
100 loops, best of 3: 2.22 ms per loop 

In [530]: %timeit sum(a32) 
1 loop, best of 3: 572 ms per loop 

In [531]: %timeit sum(a64) 
1 loop, best of 3: 604 ms per loop 

正如你看到的,你必須避免純Python循環,這是比較慢。

相關問題