1. 程式人生 > >資料分析(二)

資料分析(二)

Numpy:Numeric Python

引言:要學好機器學習,先打好資料分析的基礎,打好基礎才能實現後面那些經驗的功能

一、匯入

匯入:import numpy as np

檢視版本:np.__ version __

二、陣列ndarray

1、使用np.array()

import numpy as np
test=np.array([1,2,3,4,5])
test

2、建立多維陣列

2.1 陣列建立函式

1.指定數值建立陣列

np.eye(N=幾行(預設列數和行數相等),dtype=資料型別)

np.ones(shape=形狀,dtype=資料型別) 按照shape建立陣列,用1填充

np.zeros(shape=形狀,dtype=資料型別) 按照shape建立陣列,用0填充

np.full(shape=形狀,fill_value=陣列的值,dtype=資料型別) 按照shape建立陣列,用fill_value填充

2.指定範圍建立陣列

np.arange(start=起始值,stop=終止值,step=步長值) np.arange(1,5,1) [1,2,3,4]

np.linspace(start=起始值,stop=終止值,num=分多少份兒)

np.logspace(start=起始值,stop=終止值,num=分多少份兒)

2.2 建立隨機樣本

1、簡單隨機數

np.random.randint(low=下界,high=上屆,size=形狀)

np.random.randn(d0,d1,d2…dn) 建立一個n維陣列,值用標準正態分佈的隨機數填充

np.random.random(size=形狀) 按照size建立陣列,值用以loc為中心scale為範圍的正態分佈的隨機數填充

2、分佈

NumPy

二、ndarray的屬性

4個必記引數:

ndim:維度 shape:形狀(各維度的長度) size:總長度 dtype:元素型別

三、ndarray的基本操作

1、索引

基本索引:一維與列表完全一致 多維同理

import numpy as np
#0-10之間的隨機整數   填充提供矩陣
ndarr=np.random.randint(0,10,size=5)
ndarr #array([0,4,6,9,8])
ndarr[0]
ndarr[1]
ndarr[-1]  #8

ndarr=np.random.randint(0,10,size=(4,5))
ndarr
#array([[7, 0, 9, 4, 8],[7, 6, 0, 7, 4],[2, 3, 4, 5, 2],[1, 1, 6, 8, 1]])
ndarr[0][0]
ndarr[-1][-2]#8

高階索引:整數陣列形式的索引

nd=np.random.randint(0,10,size=(5,6))
nd
#array([[0, 4, 7, 5, 9, 7],[5, 3, 2, 9, 5, 5],[9, 2, 6, 2, 7, 7],[0, 3, 5, 4, 3, 9],[9, 1, 9, 7, 1, 3]])
nd[0][0]#普通的索引
#整數陣列的索引
nd[0,0]
nd[-1,0]
nd[-1,]
#往裡一個維度,要同時取出0 2 4
nd[-1,[0,2,4]]
nd[-1,[4,2,0]]#順序任意 可以正向取,也可以反向取,還可以隨意取,而且可以重複取
nd[-1,[2,4,0]]
nd[-1,[2,4,0,0,0,0]]#array([3,3])
#nd[[1,1],1]

#list
list1 = [[0, 4, 7, 5, 9, 7],[5, 3, 2, 9, 5, 5],[9, 2, 6, 2, 7, 7],[0, 3, 5, 4, 3, 9],[9, 1, 9, 7, 1, 3]]
list1
#[[0, 4, 7, 5, 9, 7],[5, 3, 2, 9, 5, 5],[9, 2, 6, 2, 7, 7],[0, 3, 5, 4, 3, 9],[9, 1, 9, 7, 1, 3]]
list1[0][0]#0
list1[0,0]

練習:使用陣列索引尋找指定位置的值

nd[0,0,0,0]
nd[0,0,0,-2]
nd[0,3,1,-1]
nd = np.random.randint(0,10,size=(5,4,3,7))  # 這是一個四維陣列 裡面有5個元素 裡面有4個元素 裡面有3個元素 裡面有7個元素
nd

2、切片

一維與列表切片完全一致 多維時同理

ndarr = np.random.randint(0,10,size=5)
ndarr  #array([8, 6, 5, 3, 6]
ndarr[1:4]
ndarr[0:4]
ndarr[:4]
ndarr[:]  #array([8, 6, 5, 3, 6]

一個:的形式進行切片

ndarr = np.random.randint(0,10,size=(4,5))
ndarr 
#array([[9, 0, 4, 7, 0],[1, 0, 4, 5, 6],[7, 4, 6, 8, 3],[0, 1, 0, 8, 0]])
ndarr[:2]
# 切片也是 從外往裡 一級一級切
ndarr[:,0:2]
ndarr[1:3,1:4]
ndarr[1:3,1:-1]  #array([[0, 4, 5],[4, 6, 8]])

練習取項上人頭

import matplotlib.pyplot as plt
jin = plt.imread('../backup/data/jin.png')
jin
plt.imshow(jin)
jin.shape  #(273, 411, 3)
plt.imshow(jin[25:140,170:260])

兩個::的形式進行切片和翻轉

nd = np.random.randint(0,10,size=9)
nd  #array([0, 0, 4, 9, 0, 3, 8, 6, 5])
nd[1:-1:2]  # start:stop:step
nd[::-1]
nd[::-2]  #array([5, 8, 0, 4, 0])
nd = np.random.randint(0,10,size=(5,5))
nd
#array([[2, 5, 6, 6, 3],[3, 8, 5, 8, 1],[4, 5, 3, 4, 6],[5, 8, 3, 3, 9],[4, 6, 0, 1, 6]])
nd[::2]
nd[:,::2]
nd[::2,::2]
nd[::-1]
#array([[2, 6, 3],[4, 3, 6],[4, 0, 6]])

練習:圖片的上下顛倒 左右顛倒 中心旋轉 變瘦 色值的交換(藍精靈 綠巨人)

plt.imshow(jin)  #正常圖片
jin.shape  #(273, 411, 3) 
plt.imshow(jin[::-1])  #上下顛倒
plt.imshow(jin[:,::-1])#左右顛倒 
plt.imshow(jin)
plt.imshow(jin[::-1,::-1])#中心旋轉
# r g b
# r g b
plt.imshow(jin[::-1,::-1,::-1])#藍精靈
plt.imshow(jin[:,:,:])
# r g b
# g r b
# plt.imshow(jin[:,:,[0,1,2]])
plt.imshow(jin[:,:,[1,0,2]])#綠巨人
plt.imshow(jin[::20,::20])#馬賽克

部分馬賽克

jin2 = jin.copy()
plt.imshow(jin2)
jin[25:125:5,160:260:5]
for i in range(100):
    for j in range(100):
        jin2[i+25,j+160] = jin[25:125:5,160:260:5][i//5,j//5]
plt.imshow(jin2)

3、變形

使用reshape的函式,注意引數是一個tuple!

nd = np.random.randint(0,10,size=(4,5))  
nd  #array([[2, 5, 0, 9, 6],[0, 1, 3, 3, 8],[5, 3, 9, 7, 8],[6, 0, 9, 8, 8]])
nd.size  #20
nd.reshape((5,4))  # 形狀可以任意改變 但是size不能變化
nd.reshape((10,2))
nd.reshape((2,10))
# nd.reshape((5,5))  # 25
nd.reshape((20,1))
nd.reshape((-1,1))  # -1指的是自動計算的意思
nd.reshape((1,20))
nd.reshape((1,-1))#array([[2, 5, 0, 9, 6, 0, 1, 3, 3, 8, 5, 3, 9, 7, 8, 6, 0, 9, 8, 8]])

4、連結

np.concatenate()

連結需要注意的點:

連結的引數是列表:一定要加小括號

必須維度相同 形狀相符

連結的方向預設是shape這個tuple的第一個值所代表的維度方向

可通過axis引數改變連結的方向

nd   #array([[2, 5, 0, 9, 6],[0, 1, 3, 3, 8],[5, 3, 9, 7, 8],[6, 0, 9, 8, 8]])
# 第一個引數 以元組的形式 傳入要拼接的多個ndarr
np.concatenate((nd,nd))  # 預設按照縱向拼接
# 第二個引數 axis 用來指定 拼接方向
# np.concatenate((nd,nd),axis=0)
# np.concatenate((nd,nd),axis=1)
# np.concatenate((nd,nd),axis=-1)  # -1是最裡層
np.concatenate((nd,nd),axis=-2)  #array([[2, 5, 0, 9, 6],[0, 1, 3, 3, 8],[5, 3, 9, 7, 8],[6, 0, 9, 8, 8],[2, 5, 0, 9, 6],[0, 1, 3, 3, 8], [5, 3, 9, 7, 8],[6, 0, 9, 8, 8]])

5、切分

與級聯類似,三個函式完成切分工作:

np.split

np.vsplit

np.hsplit

# ary, indices_or_sections, axis=0
# ary 要切分的陣列
# indices_or_sections 用來指定 分成幾份 或者 從哪裡分
# axis 用來指定切分的方向
np.split()
nd = np.random.randint(0,10,size=(4,4))
nd  #array([[2, 5, 2, 5],[8, 8, 8, 0],[1, 4, 8, 0],[5, 5, 1, 8]])
# np.split(nd,2)  # 按照 axis0 把ndarr分成了2份
np.split(nd,2,axis=1)
#[array([[2, 5],[8, 8],[1, 4],[5, 5]]), array([[2, 5],[8, 0],[8, 0],[1, 8]])]
np.vsplit(nd,2)
#[array([[2, 5, 2, 5],[8, 8, 8, 0]]), array([[1, 4, 8, 0],[5, 5, 1, 8]])]
np.hsplit(nd,2)
nd #array([[2, 5, 2, 5],[8, 8, 8, 0],[1, 4, 8, 0],[5, 5, 1, 8]])
# np.split(nd,2,axis=0)  # 傳入一個整數指的是 分成幾份
np.split(nd,[2, 3],axis=0)  # 傳入一個列表 可以指定在什麼位置切割
#[array([[2, 5, 2, 5],[8, 8, 8, 0]]), array([[1, 4, 8, 0]]), array([[5, 5, 1, 8]])]

6、副本

所有賦值運算不會為ndarray的任何元素建立副本。對賦值後的物件操作也會影響原陣列。

nd
#array([[2, 5, 2, 5],[8, 8, 8, 0],[1, 4, 8, 0],[5, 5, 1, 8]])
nd1 = nd  # 物件的複製都是淺層複製
nd1[0,0] = 100
nd1  #array([[100,   5,   2,   5],[  8,   8,   8,   0],[  1,   4,   8,   0], [  5,   5,   1,   8]])
nd  #array([[100,   5,   2,   5],[  8,   8,   8,   0],[  1,   4,   8,   0],[  5,   5,   1,   8]])

可使用copy()函式建立副本

# 對於ndarray物件 凡是涉及到複製後改變 又不希望影響原陣列的 都用copy (這是最保險的)
nd2 = nd.copy()  # 深層copy
nd2
# array([[100,   5,   2,   5],[  8,   8,   8,   0],[  1,   4,   8,   0],[  5,   5,   1,   8]])
# 對於列表 使用切片 也是深層複製
nd3 = nd[:]
nd3
nd3[0,0] = 300
nd3
nd

四、ndarray的聚合操作

1、求和np.sum

2、最大值最小值:np.max/np.min

3、其他聚合操作

Function Name    NaN-safe Version    Description
np.sum    np.nansum    Compute sum of elements 所有元素的和
np.prod    np.nanprod    Compute product of elements 所有元素的乘積
np.mean    np.nanmean    Compute mean of elements
np.std    np.nanstd    Compute standard deviation
np.min    np.nanmin    Find minimum value
np.max    np.nanmax    Find maximum value
np.argmin    np.nanargmin    Find index of minimum value
np.argmax    np.nanargmax    Find index of maximum value
np.any    N/A    Evaluate whether any elements are true
np.all    N/A    Evaluate whether all elements are true

示例 nd = np.random.randint(0,10,size=(3,3))

nd = np.random.randint(0,10,size=(3,3))
nd
#array([[9, 2, 2],[7, 7, 0],[1, 4, 6]])
np.sum(nd)  # 預設是對所有元素進行求和
# axis用來控制 求和的方向
np.sum(nd,axis=0)  # 豎直方向求和
np.sum(nd,axis=1)  # 水平方向求和
np.sum(nd,axis=-1)
#array([13, 14, 11])
np.prod(nd,axis=0)  #array([63, 56,  0])
nd  #array([[9, 2, 2],[7, 7, 0],[1, 4, 6]])
# 只要有ture就返回true
# np.any(nd)
np.any(nd,axis=0)  #array([ True,  True,  True])
# 是否都是True
np.all(nd)
np.all(nd,axis=0)
np.all(nd,axis=1)#array([ True, False,  True])
[1,2,3]*5  #[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
np.array([1,2,3])  #array([1, 2, 3])
# 0 1 2 3 4
# -1 -2 -3
axis=-1

np.argwhere
nd
# array([[9, 2, 2], [7, 7, 0], [1, 4, 6]])
nd==9
# array([[ True, False, False],[False, False, False],[False, False, False]])
nd>6
#array([[ True, False, False],[ True,  True, False],[False, False, False]])
# 使用argwhere 可以按照值去找 元素的索引
np.argwhere(nd==9)
np.argwhere(nd==1)
np.argwhere(nd>6)
# argwhere本身是用來找 值不是0的元素的索引的
# array([[0, 0], [1, 0], [1, 1]], dtype=int64)

np.sum 和 np.nansum 的區別 nan not a number

# NaN not a number
ndarr = np.array([1,2,3,np.nan])
ndarr
# array([ 1.,  2.,  3., nan])
np.sum(ndarr)
#nan
# np.nansum(ndarr)
np.nanprod(ndarr) #6.0
nd2 = np.random.randint(0,10,size=(2,2,2))
nd2
# array([[[3, 8],[1, 9]],[[0, 0],[0, 4]]])
np.concatenate((nd2,nd2),axis=2)
# array([[[3, 8, 3, 8],[1, 9, 1, 9]],[[0, 0, 0, 0],[0, 4, 0, 4]]]) 

五、ndarray的矩陣操作

1.基本矩陣操作

1)、算術運算子

加減乘除

ndarr=np.random.randint(0,10,size=(4,5))
nndarr
# array([[4, 5, 8, 3, 0],[9, 4, 4, 1, 5],[9, 6, 4, 0, 1],[6, 1, 6, 4, 9]])
ndarr+1
ndarr-1
ndarr*2
# array([[ 8, 10, 16,  6,  0],[18,  8,  8,  2, 10],[18, 12,  8,  0,  2],[12,  2, 12,  8, 18]])
  1. 矩陣積np.dot()

    ndarr

    array([[4, 5, 8, 3, 0],[9, 4, 4, 1, 5],[9, 6, 4, 0, 1],[6, 1, 6, 4, 9]])

    ndarr.shape

    矩陣的點積# A矩陣 和 B矩陣 做點積

    A矩陣是m行n列的矩陣# B矩陣是i行j列的矩陣

    B的行數必須得等於A的列數 i要等於n# 結果是一個 m行 j列的一個矩陣

    ndarr2 = np.random.randint(0,10,size=(5,2)) ndarr2

    array([[4, 4],[0, 9],[0, 8],[1, 5],[6, 2]])

    np.dot(ndarr,ndarr2) #array([[ 19, 140],[ 67, 119],[ 42, 124],[ 82, 119]]) nd1 = np.random.randint(0,5,size=(2,3)) nd1 #array([[1, 2, 3],[2, 0, 4]]) nd2 = np.random.randint(0,5,size=(3,1)) nd2

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

    np.dot(nd1,nd2)

    array([[10],[ 8]])

    對應位置 相乘然後相加 放回對應位置

2.廣播機制

例1: m = np.ones((2, 3)) a = np.arange(1,4,1) 求 m + a

m = np.ones((2, 3))
m  #array([[1., 1., 1.],[1., 1., 1.]])
a = np.arange(1,4,1) 
a   #array([1, 2, 3])
m + a  #array([[2., 3., 4.],[2., 3., 4.]])

例2: a = np.arange(3).reshape((3, 1)) b = np.arange(3) 求 a + b

a = np.arange(3).reshape((3, 1)) 
a # array([[0],[1],[2]])
b = np.arange(3)
b	# array([0, 1, 2])
a + b  # array([[0, 1, 2],[1, 2, 3],[2, 3, 4]])

六、ndarray的排序

1.快速排序

  1. 快速排序

np.sort()與ndarray.sort()都可以,但有區別:

  • np.sort(ndarray) 不改變輸入
  • ndarray.sort() 本地處理,不佔用空間,但改變輸入

示例 nd = np.random.randint(0,100,size=15)

ndarr = np.random.randint(0,100,size=15)
ndarr  #array([90, 86, 55, 97, 60, 36,  9, 41, 55, 71,  2, 94, 31, 59, 63])
# 可以使用 np模組帶有的 sort方法 返回排序後的陣列 (不影響原來陣列的順序)
np.sort(ndarr)
# array([ 2,  9, 31, 36, 41, 55, 55, 59, 60, 63, 71, 86, 90, 94, 97])
# 多維陣列物件 自身也帶有 排序的方法
ndarr.sort()
ndarr
#array([ 2,  9, 31, 36, 41, 55, 55, 59, 60, 63, 71, 86, 90, 94, 97])

2.部分排序

np.partition(a,k)

有的時候我們不是對全部資料感興趣,我們可能只對最小或最大的一部分感興趣。

  • 當k為正時,我們想要得到最小的k個數
  • 當k為負時,我們想要得到最大的k個數

示例 nd = np.random.randint(0,100,size=15)

ndarr = np.random.randint(0,100,size=15)
ndarr
#array([83, 57, 43, 83, 95, 73, 95,  7, 46, 26, 86, 47, 59, 45, 64])
# 10個數據庫 裡面分別有10000商品
# 計算銷量最大的前三個
# a, kth a是要排序的陣列 kth是要找最大的幾個
# np.partition(ndarr,3)  # k是3 表示尋找 最小的3個
# np.partition(ndarr,5)  # 順序可能是沒有排好的 但是最前面的5個一定是最小的5個
np.partition(ndarr,-5)
np.partition(ndarr,-4)
#array([46,  7, 43, 45, 59, 47, 26, 57, 64, 73, 83, 83, 95, 86, 95])