1. 程式人生 > 程式設計 >Python如何實現大型陣列運算(使用NumPy)

Python如何實現大型陣列運算(使用NumPy)

問題

你需要在大資料集(比如陣列或網格)上面執行計算。

解決方案

涉及到陣列的重量級運算操作,可以使用NumPy庫。NumPy的一個主要特徵是它會給Python提供一個數組物件,相比標準的Python列表而已更適合用來做數學運算。下面是一個簡單的小例子,向你展示標準列表物件和NumPy陣列物件之間的差別:

>>> # Python lists
>>> x = [1,2,3,4]
>>> y = [5,6,7,8]
>>> x * 2
[1,4,1,4]
>>> x + 10
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
TypeError: can only concatenate list (not "int") to list
>>> x + y
[1,5,8]

>>> # Numpy arrays
>>> import numpy as np
>>> ax = np.array([1,4])
>>> ay = np.array([5,8])
>>> ax * 2
array([2,8])
>>> ax + 10
array([11,12,13,14])
>>> ax + ay
array([ 6,8,10,12])
>>> ax * ay
array([ 5,21,32])
>>>

正如所見,兩種方案中陣列的基本數學運算結果並不相同。特別的,numpy中的標量運算(比如 ax * 2 或 ax + 10 )會作用在每一個元素上。另外,當兩個運算元都是陣列的時候執行元素對等位置計算,並最終生成一個新的陣列。

對整個陣列中所有元素同時執行數學運算可以使得作用在整個陣列上的函式運算簡單而又快速。比如,如果你想計算多項式的值,可以這樣做:

>>> def f(x):
... return 3*x**2 - 2*x + 7
...
>>> f(ax)
array([ 8,15,28,47])
>>>

NumPy還為陣列操作提供了大量的通用函式,這些函式可以作為math模組中類似函式的替代。比如:

>>> np.sqrt(ax)
array([ 1.,1.41421356,1.73205081,2. ])
>>> np.cos(ax)
array([ 0.54030231,-0.41614684,-0.9899925,-0.65364362])
>>>

使用這些通用函式要比迴圈陣列並使用math模組中的函式執行計算要快的多。因此,只要有可能的話儘量選擇numpy的陣列方案。

底層實現中,NumPy陣列使用了C或者Fortran語言的機制分配記憶體。也就是說,它們是一個非常大的連續的並由同類型資料組成的記憶體區域。所以,你可以構造一個比普通Python列表大的多的陣列。比如,如果你想構造一個10,000*10,000的浮點數二維網格,很輕鬆:

>>> grid = np.zeros(shape=(10000,10000),dtype=float)
>>> grid
  array([[ 0.,0.,...,0.],[ 0.,0.]])
>>>

所有的普通操作還是會同時作用在所有元素上:

>>> grid += 10
>>> grid
array([[ 10.,10.,10.],[ 10.,10.]])
>>> np.sin(grid)
array([[-0.54402111,-0.54402111,-0.54402111],[-0.54402111,-0.54402111]])
>>>

關於NumPy有一點需要特別的主意,那就是它擴充套件Python列表的索引功能 - 特別是對於多維陣列。為了說明清楚,先構造一個簡單的二維陣列並試著做些試驗:

>>> a = np.array([[1,4],[5,8],[9,11,12]])
>>> a
array([[ 1,[ 5,[ 9,12]])

>>> # Select row 1
>>> a[1]
array([5,8])

>>> # Select column 1
>>> a[:,1]
array([ 2,10])

>>> # Select a subregion and change it
>>> a[1:3,1:3]
array([[ 6,7],[10,11]])
>>> a[1:3,1:3] += 10
>>> a
array([[ 1,16,17,20,12]])

>>> # Broadcast a row vector across an operation on all rows
>>> a + [100,101,102,103]
array([[101,103,105,107],[105,117,119,111],[109,121,123,115]])
>>> a
array([[ 1,12]])

>>> # Conditional assignment on an array
>>> np.where(a < 10,a,10)
array([[ 1,10]])
>>>

討論

NumPy是Python領域中很多科學與工程庫的基礎,同時也是被廣泛使用的最大最複雜的模組。即便如此,在剛開始的時候通過一些簡單的例子和玩具程式也能幫我們完成一些有趣的事情。

通常我們匯入NumPy模組的時候會使用語句 import numpy as np 。這樣的話你就不用再你的程式裡面一遍遍的敲入numpy,只需要輸入np就行了,節省了不少時間。

如果想獲取更多的資訊,你當然得去NumPy官網逛逛了,網址是: http://www.numpy.org

以上就是Python如何實現大型陣列運算(使用NumPy)的詳細內容,更多關於Python 大型陣列運算(使用NumPy)的資料請關注我們其它相關文章!