1. 程式人生 > >機器學習系列一:Numpy

機器學習系列一:Numpy

一、numpy概述

numpy(Numerical Python)提供了python對多維陣列物件的支援:ndarray,具有向量運算能力,快速、節省空間。numpy支援高階大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫。

二、建立ndarray陣列

ndarray:N維陣列物件(矩陣),所有元素必須是相同型別。 
ndarray屬性:ndim屬性,表示維度個數;shape屬性,表示各維度大小;dtype屬性,表示資料型別。

# -*- coding: utf-8 -*-

import numpy

print '使用列表生成一維陣列'
data = [1,2,3,4]
x = numpy.array(data)
print data #列表 [1, 2, 3, 4]
print x #列印陣列 [1 2 3 4]
print x.size #列印元數的個數 4
print x.shape #列印陣列各個維度的長度 (4,)
print x.dtype #列印陣列元素的型別 int64

print '使用列表生成二維陣列'
data = [[1,2],[3,4],[5,6]]
x = numpy.array(data)
print x #列印陣列 [[1 2][3 4][5 6]]
print x.ndim #列印陣列的維度 2
print x.shape #列印陣列各個維度的長度。shape是一個元組 (3,2)

print '使用zero/ones/empty建立陣列:根據shape來建立'
x = numpy.zeros(6) #建立一維長度為6的,元素都是0一維陣列
print x
x = numpy.zeros((2,3)) #建立一維長度為2,二維長度為3的二維0陣列
print x
x = numpy.ones((2,3)) #建立一維長度為2,二維長度為3的二維1陣列
print x
x = numpy.empty((3,3)) #建立一維長度為2,二維長度為3,未初始化的二維陣列
print x

print '使用arrange生成連續元素'
print numpy.arange(6) # [0,1,2,3,4,5,] 開區間
print numpy.arange(0,6,2)  # [0, 2,4]

print '使用random生成隨機陣列:均勻分佈'
x = x.random.random((2, 3)) #建立指定形狀的陣列(範圍在0至1之間)
print x
x = np.random.rand(10, 10)#建立指定形狀(示例為10行10列)的陣列(範圍在0至1之間, 均勻分佈)
print x
x = np.random.randn(10, 10)#建立指定形狀(示例為10行10列)的陣列(標準正態分佈)
print x
x = np.random.uniform(0, 100)#建立指定範圍內的一個數
print x
x = np.random.randint(0, 100, 6).reshape(3, 2) #建立指定範圍內的一個整數陣列,3×2的陣列
print x
x = np.random.randint(0, 100, size=(4, 4)) #建立指定範圍內的一個整數陣列,4×4的陣列
print x

print '使用random生成隨機陣列:正態分佈'
x = np.random.normal(0, 0.01, (3, 4))#均值為0,方差為0.01,3×4的陣列
print x

三.ndarray的向量化計算

向量運算:相同大小的陣列鍵間的運算應用在元素上 
向量和標量運算:“廣播”— 將標量“廣播”到各個元素

print 'ndarray陣列與標量/陣列的運算'
x = numpy.array([1,2,3]) 
print x*2 # [2 4 6]
print x>2 # [False False  True]
print x == 2 #[False True False]
equal_to_two = (x == 2)
print x[equal_to_two] #[2]
y = numpy.array([3,4,5])
print x+y # [4 6 8]
print x>y # [False False False]

四.ndarray陣列的基本索引和切片

一維陣列的索引:與Python的列表索引功能相似

多維陣列的索引:

  • arr[r1:r2, c1:c2]
  • arr[1,1] 等價 arr[1][1]
  • [:] 代表某個維度的資料
print 'ndarray的基本索引'
x = numpy.array([[1,2],[3,4],[5,6]])
print x[0] # [1,2]
print x[0][1] # 2,普通python陣列的索引
print x[0,1] # 同x[0][1],ndarray陣列的索引
x = numpy.array([[[1, 2], [3,4]], [[5, 6], [7,8]]])
print x[0] # [[1 2],[3 4]]
y = x[0].copy() # 生成一個副本
z = x[0] # 未生成一個副本
print y #  [[1 2],[3 4]]
print y[0,0] # 1
y[0,0] = 0 
z[0,0] = -1
print y # [[0 2],[3 4]]
print x[0] # [[-1 2],[3 4]]
print z # [[-1 2],[3 4]]

print 'ndarray的切片'
x = numpy.array([1,2,3,4,5])
print x[1:3] # [2,3] 右邊開區間
print x[:3] # [1,2,3] 左邊預設為 0
print x[1:] # [2,3,4,5] 右邊預設為元素個數
print x[0:4:2] # [1,3] 下標遞增2
x = numpy.array([[1,2],[3,4],[5,6]])
print x[:2] # [[1 2],[3 4]]
print x[:2,:1] # [[1],[3]]
x[:2,:1] = 0 # 用標量賦值
print x # [[0,2],[0,4],[5,6]]
x[:2,:1] = [[8],[6]] # 用陣列賦值
print x # [[8,2],[6,4],[5,6]]

五.ndarray陣列的布林索引和花式索引 

布林索引:使用布林陣列作為索引。arr[condition],condition為一個條件/多個條件組成的布林陣列。

print 'ndarray的布林型索引'
x = numpy.array([3,2,3,1,3,0])
# 布林型陣列的長度必須跟被索引的軸長度一致
y = numpy.array([True,False,True,False,True,False]) 
print x[y] # [3,3,3] 
print x[y==False] # [2,1,0]
print x>=3 # [ True False  True False  True  False]
print x[~(x>=3)] # [2,1,0]
print (x==2)|(x==1) # [False  True False  True False False]
print x[(x==2)|(x==1)] # [2 1]
x[(x==2)|(x==1)] = 0
print x # [3 0 3 0 3 0]

花式索引:使用整型陣列作為索引。

print 'ndarray的花式索引:使用整型陣列作為索引'
x = numpy.array([1,2,3,4,5,6])
print x[[0,1,2]] # [1 2 3]
print x[[-1,-2,-3]] # [6,5,4]
x = numpy.array([[1,2],[3,4],[5,6]])
print x[[0,1]] # [[1,2],[3,4]]
print x[[0,1],[0,1]] # [1,4] 列印x[0][0]和x[1][1]
print x[[0,1]][:,[0,1]] # 列印01行的01列 [[1,2],[3,4]]
# 使用numpy.ix_()函式增強可讀性
print x[numpy.ix_([0,1],[0,1])] #同上 列印01行的01列 [[1,2],[3,4]]
x[[0,1],[0,1]] = [0,0]
print x # [[0,2],[3,0],[5,6]]

六.ndarray陣列的轉置和軸對換

陣列的轉置/軸對換隻會返回源資料的一個檢視,不會對源資料進行修改。

print 'ndarray陣列的轉置和軸對換'
k = numpy.arange(9) #[0,1,....8]
m = k.reshape((3,3)) # 改變陣列的shape複製生成2維的,每個維度長度為3的陣列
print k # [0 1 2 3 4 5 6 7 8]
print m # [[0 1 2] [3 4 5] [6 7 8]]
# 轉置(矩陣)陣列:T屬性 : mT[x][y] = m[y][x]
print m.T # [[0 3 6] [1 4 7] [2 5 8]]
# 計算矩陣的內積 xTx
print numpy.dot(m,m.T) # numpy.dot點乘
# 高維陣列的軸物件
k = numpy.arange(8).reshape(2,2,2)
print k # [[[0 1],[2 3]],[[4 5],[6 7]]]
print k[1][0][0]
# 軸變換 transpose 引數:由軸編號組成的元組
m = k.transpose((1,0,2)) # m[y][x][z] = k[x][y][z]
print m # [[[0 1],[4 5]],[[2 3],[6 7]]]
print m[0][1][0]
# 軸交換 swapaxes (axes:軸),引數:一對軸編號
m = k.swapaxes(0,1) # 將第一個軸和第二個軸交換 m[y][x][z] = k[x][y][z]
print m # [[[0 1],[4 5]],[[2 3],[6 7]]]
print m[0][1][0]
# 使用軸交換進行陣列矩陣轉置
m = numpy.arange(9).reshape((3,3))
print m # [[0 1 2] [3 4 5] [6 7 8]]
print m.swapaxes(1,0) # [[0 3 6] [1 4 7] [2 5 8]]

七.ndarray通用函式

通用函式(ufunc)是一種對ndarray中的資料執行元素級運算的函式。

通用函式(即ufunc)是一種對ndarray中的資料執行元素級運算的函式。你可以將其看做簡單函式(接受一個或多個標量值,併產生一個或多個標量值)的向量化包裝器。

print '一元ufunc示例'
x = numpy.arange(6)
print x # [0 1 2 3 4 5]
print numpy.square(x) # [ 0  1  4  9 16 25]
x = numpy.array([1.5,1.6,1.7,1.8])
y,z = numpy.modf(x)
print y # [ 0.5  0.6  0.7  0.8]
print z # [ 1.  1.  1.  1.]

 

 

print '二元ufunc示例'
x = numpy.array([[1,4],[6,7]])
y = numpy.array([[2,3],[5,8]])
print numpy.maximum(x,y) # [[2,4],[6,8]]
print numpy.minimum(x,y) # [[1,3],[5,7]]
A = np.array([[1,1],[0,1]])
B = np.array([[2,0],[3,4]])
print A
print B
print A*B #對應元素相乘[[2 0][0 4]]
print np.multiply(A,B)#對應元素相乘[[2 0][0 4]]
print A.dot(B) #矩陣乘法[[5 4][3 4]]
print np.dot(A,B)#矩陣乘法[[5 4][3 4]]

八.利用陣列進行資料處理

NumPy陣列使你可以將許多種資料處理任務表述為簡潔的陣列表示式(否則需要編寫迴圈)。用陣列表示式代替迴圈的做法,通常被稱為向量化。一般來說,向量化陣列運算要比等價的純Python方式快上一兩個數量級(甚至更多),尤其是各種數值計算。