[Machine Learning]Numpy

Numpy:數組

numpy提供兩種基本的對象:ndarray和ufunc,ndarray是存儲單一數據類型的多爲數組,ufunc是可以對數組進行操做的函數。函數

1.ndarray對象ui

建立數組:spa

a = numpy.array([1, 2, 3, 4])

b = np.array([[1, 2, 3, 4], [4, 5, 6, 7]])

數組的形狀能夠經過其shape屬性得到,它是一個描述數組各個軸長度的元組:code

1 a.shape
2 # 結果: (4,)
3 b.shape
4 # 結果: (2, 4)

在保持數組元素個數不變的狀況下,能夠經過改變數組shape屬性,改變數組每一個軸的大小:(數組元素在內存中的位置不變)orm

1 b.shape = 4,2
2 #結果
3 #array([[1, 2],
4 #       [3, 4],
5 #      [4, 5],
6 #       [6, 7]])

當設置某個軸的元素個數爲-1時,將自動計算此軸的長度。使用reshape()方法能夠建立指定形狀的新數組,原數組保持不變,新數組和原數組是共享存儲空間的,修改會相互影響:對象

1 c = b.reshape(2, 4)
2 #結果
3 #array([[1, 2, 3, 4],
4 #      [4, 5, 6, 7]])

數組元素的類型能夠經過dtype屬性得到:blog

c.dtype
#結果
# dtype('int64')

能夠用dtype參數在建立數組時指定元素類型,float是64bit的雙精度浮點類型,complex是128bit的雙精度複數類型:內存

1 numpy.array([1,2,3,4], dtype=np.float)

Numpy的完整的類型列表存儲在typeDict字典中,能夠將其轉換爲集合來查看:unicode

{numpy.bool_,
 numpy.object_,
 numpy.string_,
 numpy.unicode_,
 numpy.void,
 numpy.int8,
 numpy.int16,
 numpy.int32,
 numpy.int64,
 numpy.int64,
 numpy.uint8,
 numpy.uint16,
 numpy.uint32,
 numpy.uint64,
 numpy.uint64,
 numpy.float16,
 numpy.float32,
 numpy.float64,
 numpy.float128,
 numpy.datetime64,
 numpy.timedelta64,
 numpy.complex64,
 numpy.complex128,
 numpy.complex256}

arange()經過指定開始值,終止值和步長建立表示等差數列的一位數組(不包括終止值):

1 numpy.arange(0, 1, 0.1)
2 #結果
3 #array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

linspace()經過指定開始值,終止值和元素個數建立等差數列的一維數組:

1 numpy.linspace(0, 1, 10) #步長1/9
2 #結果
3 #array([ 0.        ,  0.11111111,  0.22222222,  0.33333333,  #0.44444444,
4 #        0.55555556,  0.66666667,  0.77777778,  0.88888889,  1.])
5 
6 numpy.linspace(0, 1, 10, endpoint=False) #步長1/10
7 #結果
8 #array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9])

 logspace()用於建立等比數列。

zeros(), ones, empty()能夠建立指定形狀和類型的數組, zeros_like(),ones_like(), empty_like()能夠用來建立數組的形狀及類型相同, 例如zeros_like(a) 和 zeros(a.shape, a.dtype):

numpy.empty((2, 3), numpy.int) #只分配類型,不初始化
#結果
#array([[-5764607523034234880,  6917537799820997240,           4327211011],
#      [          4327214544,           4327214608,      844424930131968]])

numpy.zeros(4, numpy.float) #元素被初始化爲0,默認類型numpy.float
#結果:
#array([ 0.,  0.,  0.,  0.])

frombuffer(),fromstring()和fromfile()等能夠從字節序列或文件建立數組:

 1 s = "abcdefg"
 2 numpy.fromstring(s, dtype=numpy.int8)
 3 #結果:
 4 #array([ 97,  98,  99, 100, 101, 102, 103], dtype=int8)
 5 
 6 s = "abcdef"
 7 numpy.fromstring(s, dtype=numpy.int16)
 8 #結果
 9 #array([25185, 25699, 26213], dtype=int16)
10 # 其中每一個元素等於兩個字節表示一個整數,98 * 256 + 97

 還能夠定義一個從下標計算數值的函數,而後使用fromfunction()建立數組:

def func(i):
    return i % 4 + 1

numpy.fromfunction(func, (10, ))
#結果
#array([ 1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.,  1.,  2.])

 存取元素:

a = numpy.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

a[5] #用整數做爲下標能夠獲取數組中的某個元素
#結果:5

a[3 : 5] #用切片做爲下標獲取數組一部分,不包括a[5]
#結果:array([3, 4])

a[2:4]=100,101 #用下標來修改元素的值
#結果:array([  0,   1, 100, 101,   4,   5,   6,   7,   8,   9])

 經過切片獲取的新數組是原數組的一個數組,它與原始數組共享同一數據空間。

使用整數列表對數組元素進行存取時,獲得的新數組不和原始數組共享數據,整數數組和布爾數組相似:

1 x = numpy.arange(10, 1, -1)
2 #array([10,  9,  8,  7,  6,  5,  4,  3,  2])
3 
4 x[[3, 3, 1, 8]] #獲取數組中下標爲3, 3, 1, 8的四個元素,組成一個新的數組

多維數組

Numpy用元組做爲數組下標,建立二維數組:

a = numpy.arange(0, 60, 10).reshape(-1, 1) + numpy.arange(0, 6)
#結果
#array([[ 0,  1,  2,  3,  4,  5],
       [10, 11, 12, 13, 14, 15],
       [20, 21, 22, 23, 24, 25],
       [30, 31, 32, 33, 34, 35],
       [40, 41, 42, 43, 44, 45],
       [50, 51, 52, 53, 54, 55]])

數據元素存取,第0個元素和數組的第0軸(縱軸)相對應,第1個元素與數組的第1軸(橫軸)對應:

1 a[0, 3:5]
2 #結果:array([3, 4])
3 
4 a[4:, 4:]
5 #array([[44, 45],
6        [54, 55]])

能夠經過建立下標元組,用同一元組存取多個數組:

1 idx = slice(None, None, 2), slice(2, None)
2 a[idx] #和a[::2, 2:]相同
3 #結果
4 #array([[ 2,  3,  4,  5],
5        [22, 23, 24, 25],
6        [42, 43, 44, 45]])

 

 1 1. a[(0, 1, 2, 3), (1, 2, 3, 4)] #相似a[0, 1], a[1, 2], a[2, 3], a[3, 4]
 2 #結果:array([ 1, 12, 23, 34])
 3 
 4 2. a[3:, [0, 2,5]] # 第0軸是個切片,選取第三行後的全部行,第1軸選取0, 2, 5列
 5 #結果:
 6 #array([[30, 32, 35],
 7        [40, 42, 45],
 8        [50, 52, 55]])
 9 
10 
11 3. mask = numpy.array([1, 0, 1, 0, 0, 1], dtype=numpy.bool)
12 a[mask, 2] #第0軸是個布爾數組選取0,2,5, 第1軸選取第2列
13 #結果array([ 2, 22, 52])
14 #注意:若是mask不是布爾數組,而是整數數組,列表或者元組,按照1運算

 當全部軸用形狀相同的整數數組做爲下標,獲得的數組和下標數組的維數相同:

1 x = numpy.array([[0 ,1], [2, 3]])
2 y = numpy.array([[-1, -2], [-3, -4]])
3 a[x, y]
4 #結果:
5 # array([[ 5, 14],
6        [23, 32]])
7 
8 #相似於
9 a[(0, 1, 2, 3), (-1, -2, -3, -4)].reshape(2, 2)

 結構數組:

1 persontype = numpy.dtype({
2    ....: "names" : ["name", "age", "weight"], #每一個字段名
3    ....: "formats" : ['S32', 'i', 'f']}, align = True) #每一個字段的類型
4 
5 a = numpy.array([("zhang", 32, 75.5), ("wang", 24, 65.2)], dtype=persontype)

 2. ufunc運算

ufunc是universal function的縮寫,它是一種能對數組中每一個元素進行操做的函數。

x = numpy.linspace(0, 2 * numpy.pi, 10)
y = numpy.sin(x) #numpy.sin()就是一個ufunc函數

數組提供了item()方法用來獲取數組中的單個元素,並直接返回標準的Python數值類型:

1 a = numpy.arange(6.0).reshape(2, 3)
2 a.item(1, 2) #和a[1,2]相似
3 type(a.item(1, 2))
4 #結果:float
5 
6 type(a[1,2])
7 #結果:numpy.float64

四則運算

a = numpy.arange(0, 4)
b = numpy.arange(1, 5)
numpy.add(a, b)
#結果array([1, 3, 5, 7])

#能夠經過指定第三個參數,保存結果
numpy.add(a, b, a) #等價於a+=b
a
#結果array([1, 3, 5, 7]) 

比較和布爾運算

使用"==",">"等比較運算符對兩個數組進行比較,將返回一個布爾數組,該數組的每一個元素值都是兩個數組對於元素的比較結果:

1 numpy.array([1, 2, 3]) < numpy.array([3, 2, 1])
2 #結果array([ True, False, False], dtype=bool)

數組中的布爾運算只能經過相應的ufunc函數進行,這些函數以"logical_開頭, 使用and, or, not將拋出異常":

1 numpy.logical_and  numpy.logical_not  numpy.logical_or   numpy.logical_xor
 1 a = numpy.arange(5)
 2 b = numpy.arange(4, -1, -1)
 3 a == b
 4 #結果:array([False, False,  True, False, False], dtype=bool)
 5 
 6 a > b
 7 #結果:array([False, False, False,  True,  True], dtype=bool)
 8 
 9 numpy.logical_or(a > b, a ==b)
10 #結果:array([False, False,  True,  True,  True], dtype=bool)

 位運算符可使用&,|, ~等,也但是使用以bitwise_開頭的比特運算符:

numpy.bitwise_and  numpy.bitwise_not  numpy.bitwise_or   numpy.bitwise_xor

注意位運算符優先級高於布爾運算符, 注意括號的使用:

1 (a == b) | (a > b)

自定義ufunc運算:

用frompyfunc()將一個計算單個元素的函數轉換成ufunc函數, frompyfunc()的調用格式:

1 frompyfunc(func, nin, nout)

其中:func是計算單個元素的函數,nin是func輸入參數的個數,nout是func返回值的個數。

 1 def triangle_wave(x, c, c0, hc):
 2     x = x - int(x)
 3     if x >= c: r= 0.0 
 4     elif x < c0: r = x/ c0 * hc
 5     else: r = (c - x) / (c - c0) * hc
 6     return r
 7 
 8 x = numpy.linspace(0, 2, 1000)
 9 #func對象
10 triangle_ufunc1 = numpy.frompyfunc(triangle_wave, 4, 1)
11 #使用
12 y2 = triangle_ufunc1(x, 0.6, 0.4, 1.0)

注意此時func返回數組的元素類型是object,能夠用astype()進行轉換

1 y2.dtype
2 #結果:dtype('O')
3 
4 y2 = y2.astype(numpy.float)

可使用vectorize()實現和frompyfunc()相同的功能,但該函數能夠經過otypes指定返回類型。

 廣播

使用ufunc對兩個數組進行運算時,要求兩個數組的形狀相同,若是不一樣,則進行廣播,規則以下:

1. 讓全部輸入數組都向其中維數最多的數組看齊,shape屬性中不足的部分經過在前面加1補齊;

2. 輸出數組的shape屬性是輸入數組的shape屬性在各軸上的最大值;

3. 若是輸入數組的某個軸長度爲1或與輸出數組對應軸的長度相同,這個數組就能用來計算,不然出錯;

4. 當輸入數組的某個軸長度爲1時,沿着此軸運算時都用此軸上的第一組值。

 1 a = numpy.arange(0, 60, 10).reshape(-1, 1)
 2 #結果:
 3 #array([[ 0],
 4        [10],
 5        [20],
 6        [30],
 7        [40],
 8        [50]])
 9 
10 a.shape
11 #結果:(6, 1)
12 
13 b = numpy.arange(0, 5)
14 b.shape
15 #結果 (5,)
16 
17 c = a + b
18 #結果
19 #array([[ 0,  1,  2,  3,  4],
20        [10, 11, 12, 13, 14],
21        [20, 21, 22, 23, 24],
22        [30, 31, 32, 33, 34],
23        [40, 41, 42, 43, 44],
24        [50, 51, 52, 53, 54]])
25 c.shape
26 #結果:(6, 5)

Numpy提供了快速產生能進行廣播運算的數組的ogrid對象:

 1 x, y = numpy.ogrid[:5, :5]
 2 x
 3 #結果
 4 #array([[0],
 5        [1],
 6        [2],
 7        [3],
 8        [4]])
 9 y
10 #結果
11 #array([[0, 1, 2, 3, 4]])
12 
13 x + y
14 #結果
15 #array([[0, 1, 2, 3, 4],
16        [1, 2, 3, 4, 5],
17        [2, 3, 4, 5, 6],
18        [3, 4, 5, 6, 7],
19        [4, 5, 6, 7, 8]])

 多維數組:

待續。。。。。。。

相關文章
相關標籤/搜索