1. 程式人生 > >Numpy常用方法及應用總彙

Numpy常用方法及應用總彙

目錄

  • Numpy
  • 1.基本操作
    • 1.1陣列轉換
    • 1.2陣列生成
    • 1.3檔案讀取
    • 1.4檢視操作
  • 2.資料型別
    • 2.1指定資料型別:
    • 2.2檢視資料型別
    • 2.3資料型別轉換
  • 3.陣列運算
    • 3.1陣列間運算
    • 3.2陣列與標量
  • 4.索引和切片
    • 4.1基本索引和切片
    • 4.2布林型索引
    • 4.3花式索引
  • 5.陣列轉置和軸對換
  • 6.陣列函式
    • 6.1通用函式:元素級數字函式
    • 6.2where函式
    • 6.3數學和統計方法
    • 6.4排序方法
    • 6.5集合運算函式
    • 線性代數

Numpy


1.基本操作

1.1陣列轉換

建立陣列的最簡單的方法就是使用array函式,將Python下的list轉換為ndarray

#通過陣列建立一個ndarray
data1 = [6,7.5,8,0,1]
arr1 = np.array(data1)
arr1
#輸出為:
array([6,7.5,8,0,1])

建立二維陣列

#通過陣列建立一個二維的ndarray
data2 = [[1,2,3,4],[5,6,7,8]]
arr2 = np.array(data2)
arr2
#輸出為:
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

重新定義矩陣的形狀
array.reshape((n,m))

1.2陣列生成

除了通過陣列轉換而來之外,我們可以利用np中的一些內建函式來建立陣列,比如我們建立全0的陣列,也可以建立全1陣列,或者等差數列陣列

建立全0陣列

np.zeros(10)
#輸出為:
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

建立全1陣列

np.ones(10)
#輸出為:
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

建立元素接近空的陣列

np.empty((3,4))
#輸出為:
array([[4.9e-324, 4.9e-324, 9.9e-324, 9.9e-324],
       [9.9e-324, 9.9e-324, 9.9e-324, 1.5e-323],
       [2.0e-323, 2.0e-323, 2.5e-323, 2.5e-323]])
注:建立初始是隨機數,而不是空,需要重新賦值

建立等差陣列

np.arange(1,15,2)
#輸出為:
array([ 1,  3,  5,  7,  9, 11, 13])

建立正態分佈隨機陣列

samples = np.random.normal(2,3,size=(4,4))
samples
#輸出為:
array([[ 6.15721917,  3.42393052,  0.65418836, -0.6927128 ],
       [ 2.79557529,  1.1205289 ,  1.63283966,  6.18085827],
       [-1.02241948, -2.77444011, -0.7293639 ,  1.9849088 ],
       [ 2.52981105,  1.80517346, -1.98852316,  1.71483645]])

建立正態分佈陣列

samples = np.random.randn(4,4)
samples
#輸出為:
array([[-0.96184087,  0.86026662,  1.13674982,  2.74464916],
       [ 0.14419425, -0.57185231,  0.61601683, -0.18976333],
       [-0.25594082, -1.84514383,  0.54483433,  1.77408903],
       [-0.16996494,  0.18802037,  1.54856742,  0.18296107]])

randint生成隨機整數陣列

samples = np.random.randint(0,10,size=(3,4))
samples
#輸出為:
array([[6, 7, 2, 2],
       [1, 3, 5, 6],
       [5, 8, 4, 9]])

1.3檔案讀取

save方法儲存ndarray到一個npy檔案,也可以使用savez將多個array儲存到一個.npz檔案中:

x = np.array([1,2,4,5])
y = np.array([3,4,5])
#save方法可以存取一個ndarray
np.save("x_arr",x)
#如果要存取多個數組,要是用savez方法
np.savez("some_array.npz",xarr = x,yarr=y)

load方法來讀取儲存的陣列,如果是.npz檔案的話,讀取之後相當於形成了一個k-v型別的變數,通過儲存時定義的key來獲取相應的array。

np.load('x_arr.npy')
#array([1, 2, 4, 5])
arch = np.load("some_array.npz")
arch['yarr']
#array([3, 4, 5])

np.loadtxt 和 np.savetxt可以用來存取txt或csv檔案

arr=[[6, 7, 2, 2],
    [1, 3, 5, 6],
    [5, 8, 4, 9]]
#儲存陣列到txt檔案
np.savetxt("array_ex.txt",arr)
#讀取txt檔案,delimiter為分隔符,dtype為資料型別
np.loadtxt("array_ex.txt",delimiter=" ",dtype=np.int32)

1.4檢視操作

檢視維度

array.ndim

檢視形狀

array.shape

檢視元素個數

array.size

2.資料型別

ndarray的資料型別:

  • int: int8、int16、int32、int、64
  • float: float16、float32、float64
  • string

2.1指定資料型別:

#指定array的資料型別
arr1 = np.array([1,2,3],dtype=np.int32)
arr2 = np.array([1,2,3],dtype=np.float32)

輸出為:

#arr1
array([1, 2, 3], dtype=int32)
#arr2
array([1., 2., 3.], dtype=float32)

2.2檢視資料型別

#檢視array的資料型別
arr2.dtype
### dtype('float32')

2.3資料型別轉換

使用astype將一個數組的資料型別進行轉換,這樣會返回一個新的陣列,對原陣列不會產生影響

#資料型別進行轉換,會產生一個新的array,原array不產生影響
arr1.astype(np.float32)
arr1.dtype
# dtype('int32')

如果一個數組中的字串只含有數字,可以將string轉換為數值形式:

numeric_strings = np.array(['1.25','0.96','42'],dtype=np.string_)
numeric_strings.astype(np.float32)
# array([  1.25      ,   0.95999998,  42.        ], dtype=float32)

3.陣列運算

3.1陣列間運算

大小相等的陣列之間的任何算數運算都會應用到元素身上

arr = np.array([[1,2,3],[4,5,6]],dtype=np.float32)
arr * arr

#array([[  1.,   4.,   9.],
#       [ 16.,  25.,  36.]], dtype=float32)

arr - arr

#array([[ 0.,  0.,  0.],
 #      [ 0.,  0.,  0.]], dtype=float32)

不同維度陣列間的計算,低維陣列每個元素分別與高維陣列計算

a = np.array([[1,2,3,4],[6,7,8,9]])
b = np.arange(1,5)
print(a+b)
#       array([[ 2,  4,  6,  8],
       [ 7,  9, 11, 13]])

print(a*b)
#       array([[ 2,  4,  6,  8],
        [ 7,  9, 11, 13]])

print(a/b)
#       array([[ 2,  4,  6,  8],
       [ 7,  9, 11, 13]])

3.2陣列與標量

陣列與標量的算術運算也會將標量值傳播到各個元素:

1 / arr

#array([[ 1.        ,  0.5       ,  0.33333334],
#       [ 0.25      ,  0.2       ,  0.16666667]], dtype=float32)

4.索引和切片

4.1基本索引和切片

numpy中陣列切片是原始陣列的檢視,這意味著資料不會被複制,檢視上任何資料的修改都會反映到原陣列上。

arr = np.arange(10)
arr[5]
# 5
arr[5:8]
#array([5, 6, 7])
arr[5:8]=12 #切片賦值會賦值到每個元素上,與列表操作不同
t = arr[5:8]
t[1] = 12345
arr
#array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,     9])

使用copy方法,可以看到使用copy之後再修改資料不會影響到原資料:

t1 = arr[5:8].copy()
t1[2] = -222
arr

#array([ 0,  1,  2,  3,  4, 64, 64, 64,  8,  9])

對於二維陣列或者高維陣列,我們可以按照之前的知識來索引,當然也可以傳入一個以逗號隔開的索引列表來選區單個或多個元素

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr2d[0,2] #(等於arr2d[0][2])
#3

arr2d[:2,1:] #等於arr2d[:2][:,1:]
#array([[2, 3],
#       [5, 6]])

4.2布林型索引

names = np.array(['Bob','Joe','Will','Bob','Will','Joe','Joe'])
data = np.random.randn(7,4)

names == 'Bob'
#array([ True, False, False,  True, False, False, False], dtype=bool)

data[names=='Bob']
#array([[ 0.75323688,  0.85622553, -2.71974541,  0.37865467],
#       [ 1.35356641,  0.09263267,  1.96207471, -0.05549953]])

布林型索引邏輯運算,“|” 表示或 “&”表示 與

data[(names=='Bob')| (names=='Will')]

#array([[ 0.75323688,  0.85622553, -2.71974541,  0.37865467],
       [ 0.93720776, -1.49360063, -0.06471438,  0.62149438],
       [ 1.35356641,  0.09263267,  1.96207471, -0.05549953],
       [ 1.87344915,  1.75085643,  1.9197879 ,  0.47687361]])

4.3花式索引

花式索引的方式,它指利用整數陣列進行索引,花式索引和切片不一樣,它總是將資料複製到新陣列中

arr = np.empty((8,4))
for i in range(8):
    arr[i] = i
arr[[4,3,0,6]]

輸出為:

array([[ 4.,  4.,  4.,  4.],
       [ 3.,  3.,  3.,  3.],
       [ 0.,  0.,  0.,  0.],
       [ 6.,  6.,  6.,  6.]])

選擇一塊方形區域,同時按照我們指定的順序排列資料,我們嘗試以下的方式:

arr = np.arange(32).reshape((8,4))
arr[[1,5,7,2],[0,3,1,2]]

輸出為:

array([ 4, 23, 29, 10])

這是因為按照上面的方式進行選取,會將選擇出的元素鎖定在4個元素上。
正確的方式有下面兩種:

arr[[1,5,7,2]][:,[0,3,1,2]]
arr[np.ix_([1,5,7,2],[0,3,1,2])]

輸出為:

array([[ 4,  7,  5,  6],
       [20, 23, 21, 22],
       [28, 31, 29, 30],
       [ 8, 11,  9, 10]])

5.陣列轉置和軸對換

轉置T屬性:

arr = np.arange(15).reshape((5,3))
arr.T

#array([[ 0,  3,  6,  9, 12],
       [ 1,  4,  7, 10, 13],
       [ 2,  5,  8, 11, 14]])

對於高維陣列,tranpose需要得到一個由軸編號組成的元組才能對這些軸進行轉置,太費腦子:

arr.transpose((1,0,2))
#array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

6.陣列函式

6.1通用函式:元素級數字函式

  • 一元函式:
    abs 絕對值
    sqrt 開方
    square 平方根
    exp e的冪次方
    log 對數函式
    sin/cos/tan 三角函式
  • 二元函式:
    maxinmum 最大值
    minimum 最小值
arr = np.arange(10)
np.sqrt(arr)

x = np.random.randn(8)
y = np.random.randn(8)
np.maximum(x,y)
#array([ 0.68417031,  0.22971426,  1.69724546,  1.19366822, -0.79176777, -0.43557768,  0.66628223,  0.85093113])

6.2where函式

where 函式,三個引數,條件為真時選擇值的陣列,條件為假時選擇值的陣列:

xarr = np.array([1.1,1.2,1.3,1.4,1.5])
yarr = np.array([2.1,2.2,2.3,2.4,2.5])
cond = np.array([True,False,True,True,False])
np.where(cond,xarr,yarr)

輸出為:

array([ 1.1,  2.2,  1.3,  1.4,  2.5])

也可以使用下面的形式,後兩個引數為指定值:

np.where(xarr>1.2,2,-2)
#array([-2, -2,  2,  2,  2])

6.3數學和統計方法

數學和統計方法既可以當作陣列的例項方法呼叫,也可以當作numpy函式呼叫,比如下面兩種計算陣列均值的方法是等效的:

arr = np.random.randn(5,4)
arr.mean()
np.mean(arr)

mean,sum,max,min這一類函式可以接受一個axis引數,用於計算該軸向上的統計值,最終結果是一個少一維的陣列。對於一個二維陣列,axis=0相當於按列操作,最終元素的個數和第二維的大小相同,axis=1相當於按行操作,最終元素的個數和第一維的大小相同:

arr.mean(axis=1)
#array([ 0.29250253, -0.50119163,  0.11746254,  0.23338843,  0.15912472])

arr.sum(0)
#array([ 1.92728592,  0.67480797, -2.8398905 ,  1.44294295])

我們也可以用cumsum(累加值計算)和cumprod(累積值計算)保留中間計算結果:

arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
arr.cumsum(0)

#array([[ 1,  2,  3],
       [ 5,  7,  9],
       [12, 15, 18]])

arr.cumprod(1)
#array([[  1,   2,   6],
       [  4,  20, 120],
       [  7,  56, 504]])

6.4排序方法

np中還提供了排序方法,排序方法是就地排序,即直接改變原陣列:

arr = np.random.randn(8)
arr
#array([-0.85668922, -2.0049649 , -0.89885165, -0.04185277,  0.73736138,-0.03509021, -1.89745107, -2.36576122])

arr.sort()
arr
#array([-2.36576122, -2.0049649 , -1.89745107, -0.89885165, -0.85668922,-0.04185277, -0.03509021,  0.73736138])

6.5集合運算函式

unique計算x中的唯一元素,並返回有序結果

arr = np.array([1,3,2,5,2,4,2,2,1,4,5,2])
np.unique(arr)
#array([1, 2, 3, 4, 5])

numpy提供了下面三個常見的集合運算函式:
intersect1d(x,y) 用於計算x和y的公共結果,並返回有序結果
union1d(x,y) 用於計算x和y的並集,並返回有序結果
setdiff1d(x,y),集合的差,即元素在x中不在y中

x = np.array([1,2,4,5])
y = np.array([3,4,5])
np.intersect1d(x,y)
#array([4, 5])
np.union1d(x,y)
#array([1, 2, 3, 4, 5])
np.setdiff1d(x,y)
#array([1, 2])

線性代數

矩陣的乘積

#矩陣的乘積
x = np.array([[1,2,3],[4,5,6]])
y = np.array([[6,23],[-1,7],[8,9]])
np.dot(x,y)

下面可以計算矩陣的逆、行列式、特徵值和特徵向量、qr分解值,svd分解值:

#計算矩陣的逆
from numpy.linalg import inv,det,eig,qr,svd
t = np.array([[1,2,3],[2,3,4],[4,5,6]])
inv(t)

#計算矩陣行列式
det(t)

#計算QR分解址
qr(t)

#計算奇異值分解值svd
svd(t)

#計算特徵值和特徵向量
eig(t)