問(wèn)題
你需要在大數(shù)據(jù)集(比如數(shù)組或網(wǎng)格)上面執(zhí)行計(jì)算。
解決方案
涉及到數(shù)組的重量級(jí)運(yùn)算操作,可以使用NumPy庫(kù)。NumPy的一個(gè)主要特征是它會(huì)給Python提供一個(gè)數(shù)組對(duì)象,相比標(biāo)準(zhǔn)的Python列表而已更適合用來(lái)做數(shù)學(xué)運(yùn)算。下面是一個(gè)簡(jiǎn)單的小例子,向你展示標(biāo)準(zhǔn)列表對(duì)象和NumPy數(shù)組對(duì)象之間的差別:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
>>> # Python lists >>> x = [ 1 , 2 , 3 , 4 ] >>> y = [ 5 , 6 , 7 , 8 ] >>> x * 2 [ 1 , 2 , 3 , 4 , 1 , 2 , 3 , 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 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] >>> # Numpy arrays >>> import numpy as np >>> ax = np.array([ 1 , 2 , 3 , 4 ]) >>> ay = np.array([ 5 , 6 , 7 , 8 ]) >>> ax * 2 array([ 2 , 4 , 6 , 8 ]) >>> ax + 10 array([ 11 , 12 , 13 , 14 ]) >>> ax + ay array([ 6 , 8 , 10 , 12 ]) >>> ax * ay array([ 5 , 12 , 21 , 32 ]) >>> |
正如所見(jiàn),兩種方案中數(shù)組的基本數(shù)學(xué)運(yùn)算結(jié)果并不相同。特別的,numpy中的標(biāo)量運(yùn)算(比如 ax * 2 或 ax + 10 )會(huì)作用在每一個(gè)元素上。另外,當(dāng)兩個(gè)操作數(shù)都是數(shù)組的時(shí)候執(zhí)行元素對(duì)等位置計(jì)算,并最終生成一個(gè)新的數(shù)組。
對(duì)整個(gè)數(shù)組中所有元素同時(shí)執(zhí)行數(shù)學(xué)運(yùn)算可以使得作用在整個(gè)數(shù)組上的函數(shù)運(yùn)算簡(jiǎn)單而又快速。比如,如果你想計(jì)算多項(xiàng)式的值,可以這樣做:
1
2
3
4
5
6
|
>>> def f(x): ... return 3 * x * * 2 - 2 * x + 7 ... >>> f(ax) array([ 8 , 15 , 28 , 47 ]) >>> |
NumPy還為數(shù)組操作提供了大量的通用函數(shù),這些函數(shù)可以作為math模塊中類似函數(shù)的替代。比如:
1
2
3
4
5
|
>>> np.sqrt(ax) array([ 1. , 1.41421356 , 1.73205081 , 2. ]) >>> np.cos(ax) array([ 0.54030231 , - 0.41614684 , - 0.9899925 , - 0.65364362 ]) >>> |
使用這些通用函數(shù)要比循環(huán)數(shù)組并使用math模塊中的函數(shù)執(zhí)行計(jì)算要快的多。因此,只要有可能的話盡量選擇numpy的數(shù)組方案。
底層實(shí)現(xiàn)中,NumPy數(shù)組使用了C或者Fortran語(yǔ)言的機(jī)制分配內(nèi)存。也就是說(shuō),它們是一個(gè)非常大的連續(xù)的并由同類型數(shù)據(jù)組成的內(nèi)存區(qū)域。所以,你可以構(gòu)造一個(gè)比普通Python列表大的多的數(shù)組。比如,如果你想構(gòu)造一個(gè)10,000*10,000的浮點(diǎn)數(shù)二維網(wǎng)格,很輕松:
1
2
3
4
5
6
7
8
9
10
|
>>> grid = np.zeros(shape = ( 10000 , 10000 ), dtype = float ) >>> grid array([[ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], ..., [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ], [ 0. , 0. , 0. , ..., 0. , 0. , 0. ]]) >>> |
所有的普通操作還是會(huì)同時(shí)作用在所有元素上:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
>>> grid + = 10 >>> grid array([[ 10. , 10. , 10. , ..., 10. , 10. , 10. ], [ 10. , 10. , 10. , ..., 10. , 10. , 10. ], [ 10. , 10. , 10. , ..., 10. , 10. , 10. ], ..., [ 10. , 10. , 10. , ..., 10. , 10. , 10. ], [ 10. , 10. , 10. , ..., 10. , 10. , 10. ], [ 10. , 10. , 10. , ..., 10. , 10. , 10. ]]) >>> np.sin(grid) array([[ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ], [ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ], [ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ], ..., [ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ], [ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ], [ - 0.54402111 , - 0.54402111 , - 0.54402111 , ..., - 0.54402111 , - 0.54402111 , - 0.54402111 ]]) >>> |
關(guān)于NumPy有一點(diǎn)需要特別的主意,那就是它擴(kuò)展Python列表的索引功能 - 特別是對(duì)于多維數(shù)組。為了說(shuō)明清楚,先構(gòu)造一個(gè)簡(jiǎn)單的二維數(shù)組并試著做些試驗(yàn):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
>>> a = np.array([[ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ]]) >>> a array([[ 1 , 2 , 3 , 4 ], [ 5 , 6 , 7 , 8 ], [ 9 , 10 , 11 , 12 ]]) >>> # Select row 1 >>> a[ 1 ] array([ 5 , 6 , 7 , 8 ]) >>> # Select column 1 >>> a[:, 1 ] array([ 2 , 6 , 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 , 2 , 3 , 4 ], [ 5 , 16 , 17 , 8 ], [ 9 , 20 , 21 , 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 , 2 , 3 , 4 ], [ 5 , 16 , 17 , 8 ], [ 9 , 20 , 21 , 12 ]]) >>> # Conditional assignment on an array >>> np.where(a < 10 , a, 10 ) array([[ 1 , 2 , 3 , 4 ], [ 5 , 10 , 10 , 8 ], [ 9 , 10 , 10 , 10 ]]) >>> |
討論
NumPy是Python領(lǐng)域中很多科學(xué)與工程庫(kù)的基礎(chǔ),同時(shí)也是被廣泛使用的最大最復(fù)雜的模塊。即便如此,在剛開(kāi)始的時(shí)候通過(guò)一些簡(jiǎn)單的例子和玩具程序也能幫我們完成一些有趣的事情。
通常我們導(dǎo)入NumPy模塊的時(shí)候會(huì)使用語(yǔ)句 import numpy as np 。這樣的話你就不用再你的程序里面一遍遍的敲入numpy,只需要輸入np就行了,節(jié)省了不少時(shí)間。
如果想獲取更多的信息,你當(dāng)然得去NumPy官網(wǎng)逛逛了,網(wǎng)址是: http://www.numpy.org
以上就是Python如何實(shí)現(xiàn)大型數(shù)組運(yùn)算(使用NumPy)的詳細(xì)內(nèi)容,更多關(guān)于Python 大型數(shù)組運(yùn)算(使用NumPy)的資料請(qǐng)關(guān)注服務(wù)器之家其它相關(guān)文章!
原文鏈接:https://www.kancloud.cn/kancloud/python3-cookbook/47184