1. 程式人生 > 實用技巧 >1、Python 資料分析-NumPy科學計算

1、Python 資料分析-NumPy科學計算

1、簡介:

1.1、什麼是資料分析

  • 把隱藏在一些看似雜亂無章的資料背後的資訊提煉出來,總結出所研究物件的內在規律,它在生活中處處都能遇到,形影不離。
    • 使得資料的價值最大化
      • 分析使用者的消費行為
        • 制定促銷活動的方案
        • 制定促銷時間和粒度
        • 計算使用者的活躍度
        • 分析產品的回購力度
      • 分析廣告點選率
        • 決定投放時間
        • 制定廣告定向人群方案
        • 決定相關平臺的投放
      • ......
  • 資料分析是用適當的方法對收集來的大量資料進行分析,幫助人們做出判斷,以便採取適當的行動
    • 保險公司從大量賠付申請資料中判斷哪些為騙保的可能
    • 支付寶通過從大量的使用者消費記錄和行為自動調整花唄的額度
    • 短視訊平臺通過使用者的點選和觀看行為資料針對性的給使用者推送喜歡的視訊

1.2、資料分析實現流程

  • 提出問題

  • 準備資料

  • 分析資料

  • 獲得結論

  • 成果視覺化

2、資料分析三劍客

  • NumPy
  • Pandas【*】
  • Matplotlib

3、numpy模組

  • NumPy(Numerical Python) 是 Python 語言中做科學計算的基礎庫。重在於數值計算,也是大部分Python科學計算庫的基礎,多用於在大型、多維陣列上執行的數值運算。
  • Python中的列表屬於高階陣列,跟陣列一樣,都屬於容器

4、numpy安裝

pip install numpy

5、numpy的操作

匯入:

import numpy as np

np.array()建立

array()建立一個一維陣列

arr_1 = np.array([1,2,3,4])

>>>
array([1, 2, 3, 4])

array()建立一個二維陣列

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

>>>
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

多維陣列就是列表中巢狀多個列表

  • 陣列和列表的區別是什麼?
    • 陣列中儲存的資料元素型別必須是統一型別
    • 優先順序:
      • 字串 > 浮點型 > 整數

6、plt檢視矩陣

引用matplotlib的pyplot模組檢視圖片的陣列

import matplotlib.pyplot as plt
plt.imread('./dog.jpg')
>>>
array([[[183, 175, 172],
        [183, 175, 172],
        [182, 174, 171],
        ... ... ...
        [ 97,  64,  57],
        [ 97,  64,  57],
        [ 97,  64,  57]]], dtype=uint8)
  • 將外部的一張圖片讀取載入到numpy陣列中,
import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
plt.imshow(dog_arr)

嘗試改變陣列元素的數值檢視對原始圖片的影響

import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
plt.imshow(dog_arr-100)

7、numpy的routines函式構造矩陣幾種方式細緻解析

  • zero()
  • ones()
  • linespace()
  • arange()
  • random系列

zero()

zeros()返回一個全0的n維陣列,一共有三個引數:shape(用來指定返回陣列的大小)、dtype(陣列元素的型別)、order(是否以記憶體中的C或Fortran連續(行或列)順序儲存多維資料)。後兩個引數都是可選的,一般只需設定第一個引數。
import numpy as np
np.zeros(5)
>>>
array([ 0.,  0.,  0.,  0.,  0.])


np.zeros((5,), dtype=np.int)
>>>
array([0, 0, 0, 0, 0])

np.zeros((2, 1))
>>>
array([[ 0.],
       [ 0.]])

ones()

ones()返回一個全1的n維陣列,同樣也有三個引數:shape(用來指定返回陣列的大小)、dtype(陣列元素的型別)、order(是否以記憶體中的C或Fortran連續(行或列)順序儲存多維資料)。後兩個引數都是可選的,一般只需設定第一個引數。和zeros一樣
np.ones(5)
>>>
array([ 1.,  1.,  1.,  1.,  1.])

np.ones((5,), dtype=np.int)
>>>
array([1, 1, 1, 1, 1])

np.ones((2, 1))
>>>
array([[ 1.],
       [ 1.]])

linespace()

生成指定範圍內指定個數的一維陣列
linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None):

- 在指定的間隔[“start”,“stop”]內均勻地返回數字。
- “num”返回num個等間距的樣本。
- endpoint是一個bool型別的值,如果為"Ture",“stop"是最後一個值,如果為"False”,生成的陣列不會包含"stop"值
- retstep是一個bool型別的值,如果為"Ture",會返回樣本之間的間隙。
  其他相似的函式 
-  arange 和 linespace 相似,但是使用步長而不是樣本的數量來確定生成樣本的數量。
np.linspace(2.0, 3.0, num=5)#等差數列返回一個一維陣列
>>>
array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])

np.linspace(2.0, 3.0, num=5, endpoint=False)
>>>array([ 2. ,  2.2,  2.4,  2.6,  2.8])

np.linspace(2.0, 3.0, num=5, retstep=True)
>>>
(array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)

arange()

返回一個有終點和起點的固定步長的排列
1)一個引數時,終點,起點預設值0,步長預設值1。
2)兩個引數時,起點,終點,步長預設值1。
3)三個引數時,起點,終點,步長。其中步長支援小數
np.arange(5)
>>>
array([0, 1, 2, 3, 4])

np.arange(5,8)
>>>
array([5, 6, 7])

np.arange(5,15,3)
>>>
array([ 5,  8, 11, 14])

random系列

np.random.randint(low, high=None, size=None, dtype='l')

作用:生成指定區間[low, high)的隨機整數
引數:
-- low: 最小值,int型
-- high: 最大值,int型
-- size: 陣列維度,int型或由int構成的tuple型
-- dtype: 資料型別,預設為np.int
返回:int型或者由int構成的ndarray

np.random.randint(4) # 只有一個引數,預設生成一個[0, 4)的隨機整數
>>>3
np.random.randint(1, 4) # 兩個引數,生成一個在[1, 4)的隨機整數
>>>
2
np.random.randint(4,size=3) # 生成3個[0, 4)的隨機整數
>>>
array([0, 2, 3])

np.random.randint(-2,5,size=(2,4)) # 在[-2,5]區間上,生成shape為2*4的隨機整數
>>>
array([[ 2,  0,  0,  2],
       [ 1, -2,  1,  3]])

np.random.rand(d0, d1, ..., dn)

作用:生成[0, 1)之間的指定形狀的隨機浮點數
引數:d0, d1, ..., dn,int型別,如不寫則返回單個隨機數
返回:ndarray型別,形狀(d0, d1, ..., dn)
np.random.rand() # 沒有引數則直接生成一個[0,1)區間的隨機數
>>>
0.1065982531337718

np.random.rand(3) # 只有一個引數則生成n*1個隨機數
>>>
array([0.24640203, 0.81910232, 0.79941588])

np.random.rand(2, 3, 4) # 有多個引數,則生成對應形狀隨機數,如本例生成shape為2*3*4的隨機數
>>>
array([[[0.73222489, 0.80656115, 0.65878337, 0.69227656],
        [0.84919565, 0.24966801, 0.48942496, 0.22120944],
        [0.98766801, 0.94405934, 0.03942681, 0.70557517]],

       [[0.92524832, 0.18057535, 0.56794523, 0.9154883 ],
        [0.03394598, 0.69742027, 0.29734901, 0.9243962 ],
        [0.97105825, 0.94426649, 0.47421422, 0.86204265]]])

np.random.randn(d0, d1, ..., dn)

作用:生成指定形狀,服從標準正態分佈(均值為0,標準差為1)的隨機數
引數:d0, d1, ..., dn,int型,如不寫則返回單個標準正態分佈例項
返回:ndarray型別,形狀(d0, d1, ..., dn)
np.random.randn() # 沒有引數則直接隨機生成一個標準正態分佈例項
>>>
0.4125703966441225

np.random.randn(3) # 只有一個引數則生成n*1的服從標準正態分佈的隨機數
>>>
array([-1.9296846 , -0.65058484,  1.04354591])

np.random.randn(2, 3, 4) # 有多個引數,則生成對應形狀標準正態分佈隨機數,如本例生成shape為2*3*4的服從標準正態分佈的隨機數
>>>
array([[[ 0.86776502,  0.28303221, -1.34946357,  0.58550346],
        [ 0.71339959,  0.04701721,  1.22317095, -0.68343179],
        [-0.50985758, -2.48461158,  0.91982751,  0.31386196]],

       [[-1.68182033, -1.758599  , -0.87263063,  0.79365794],
        [-0.30036049, -0.80478692, -1.00611589, -1.05091196],
        [-1.9336783 , -1.20739583, -1.07057808,  0.68262324]]])

np.random.random(size=None)

作用:從給定的一維陣列中生成隨機數
引數:
-- a: 一維陣列或int型
-- size: 陣列維度,int型或由int構成的tuple型
-- replace: 布林型,False時生成的隨機數無重複
-- p: 為a的資料設定概率,不設定時預設為均勻分佈
返回:單個樣本或多個樣本構成的ndarray型別
np.random.random() # 沒有引數,直接生成一個[0, 1)區間隨機浮點數
>>> 
0.15893828327675652

np.random.random(3) # 一個引數,生成[0, 1)區間shape為3*1的隨機浮點數
>>> 
array([0.77282278, 0.23005368, 0.13133513])

np.random.random(size=(3, 4)) # tuple型引數,生成[0, 1)區間shape為3*4的隨機浮點數
>>> 
array([[0.86805432, 0.96323665, 0.03130231, 0.73127007],
       [0.90952451, 0.85736009, 0.96452047, 0.76009408],
       [0.44229876, 0.31195199, 0.32074274, 0.72442267]])

np.random.choice(a, size=None, replace=True, p=None)

作用:從給定的一維陣列中生成隨機數
引數:
-- a: 一維陣列或int型
-- size: 陣列維度,int型或由int構成的tuple型
-- replace: 布林型,False時生成的隨機數無重複
-- p: 為a的資料設定概率,不設定時預設為均勻分佈
返回:單個樣本或多個樣本構成的ndarray型別
np.random.choice([1, 3, 5, 7]) # 只有一個引數a,從a中隨機選一個
>>>
7

np.random.choice([1, 3, 5, 7], size=2) # 指定size,從a中隨機選2個
>>>
array([1, 7])

np.random.choice([1, 3, 5, 7], size=(2, 3)) # size為tuple,從a中隨機選2*3個
>>> 
array([[5, 3, 3],
       [1, 1, 3]])

np.random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9], size=(2, 3), replace=False) # replace設定為false時,生成的隨機數不重複
>>> 
array([[7, 2, 6],
       [4, 1, 5]])

np.random.choice([1, 2, 3, 4], size=2, p=(0.1, 0.2, 0.3, 0.4)) # 設定p,根據p的權重隨機挑選
>>> 
array([4, 4])

更多詳細用法參照官方文件:https://numpy.org/devdocs/reference/

8、numpy的常用屬性

  • shape #返回陣列的形狀:幾行幾列
  • ndim #返回陣列的維度
  • size #返回陣列元素中總共有多少個元素
  • dtype #返回的是陣列元素的資料型別
a = np.arange(15).reshape(3, 5)
>>>
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
       
a.shape
>>>
(3, 5)

a.ndim
>>>
2

a.size
>>>
15

a.dtype
>>>
dtype('int32')

9、numpy的資料型別

  • array(dtype=?):可以設定資料型別
  • arr.dtype = '?':可以修改資料型別

arr = np.array([1,2,3],dtype="int64")
>>>
dtype('int64')

arr.dtype = 'float32'
>>>
dtype('float32')

10、numpy的索引和切片操作

10.1、索引操作

a = np.arange(15).reshape(3, 5)
a
>>>
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
a[2][1]		#索引取值
>>>
11

10.2、切出前兩行資料

a = np.arange(15).reshape(3, 5)
a[:2]
>>>
array([[0, 1, 2, 3, 4],
		[5, 6, 7, 8, 9]])

10.3、切出前兩列資料

a = np.arange(15).reshape(3, 5)
a[:,0:2]		#逗號左邊是陣列的第一個維度,右邊是第二個維度
>>>
array([[ 0,  1],
       [ 5,  6],
       [10, 11]])

10.4、切出前兩行的前兩列的資料

a = np.arange(15).reshape(3, 5)
a[:,0:2]		
>>>
array([[0, 1],
       [5, 6]])

10.5、陣列資料翻轉

a = np.arange(15).reshape(3, 5)
print(a)		#多維顯示
>>>
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

a[::-1]			#行倒置
>>>
array([[10, 11, 12, 13, 14],
       [ 5,  6,  7,  8,  9],
       [ 0,  1,  2,  3,  4]])

a[:,::-1]		#列倒置
>>>
array([[ 4,  3,  2,  1,  0],
       [ 9,  8,  7,  6,  5],
       [14, 13, 12, 11, 10]])

a[::-1,::-1]	#行列倒置
>>>

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

10.6、將一張圖片上下左右進行翻轉操作

#將圖片上下翻轉
import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
plt.imshow(dog_arr[::-1])

#將圖片左右翻轉
import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
plt.imshow(dog_arr[:,::-1,:])

#將圖片顏色進行反轉
import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
plt.imshow(dog_arr[:,:,::-1])

10.7、將圖片進行指定區域的裁剪

11、變形reshape

  • 注意:變形前和變形後陣列元素的個數是不可以改變
b = np.random.randint(0,100,size=(4,6))
>>>
array([[66,  7, 47,  0, 34, 19],
       [74, 99, 41, 49, 85,  1],
       [88, 78, 43, 78, 57, 93],
       [68, 67, 70, 55, 68, 14]])

b.reshape((3,8))
>>>
array([[59, 18, 21, 42, 33,  6, 20, 92],
       [92, 10, 39,  7, 27, 37, 90, 64],
       [95, 95, 73, 72, 94,  2, 60, 11]])

b.reshape((2,-1))		#-1表示自動計算
>>>
array([[54, 75, 43, 89, 18, 38, 60,  6, 82, 29, 40, 41],
       [27, 35, 64, 16, 18, 53, 26, 84,  6, 94, 14, 67]])

12、級聯操作concatenate函式

- 將多個numpy陣列進行橫向或者縱向的拼接
  • axis軸向的理解
    • 0:控制列
    • 1:控制行
  • 問題:
    • 級聯的兩個陣列維度一樣,但是行列個數不一樣會如何?
      • 必須保證行或列相同的情況下進行級聯操作,否則報錯
c = np.random.randint(0,20,size=(3,4))
d = np.random.randint(0,20,size=(3,2))
np.concatenate((c,d),axis=1)
>>>
array([[ 2, 14, 12, 11,  0, 12],
       [ 8, 12,  5,  3,  7,  0],
       [10,  0, 13,  9,  0, 18]])

12.1、製作圖片九宮格

import matplotlib.pyplot as plt
dog_arr = plt.imread('./dog.jpg')
arr_3 = np.concatenate((dog_arr,dog_arr,dog_arr),axis=1)
arr_9 = np.concatenate((arr_3,arr_3,arr_3),axis=0)
plt.imshow(arr_9)

13、 常用的聚合操作

sum,max,min,mean

d = np.random.randint(0,20,size=(3,2))
print(d)
d.sum(axis=1)#求所有行的和
>>>
[[10  3]
 [ 3  3]
 [ 8  2]]
array([13,  6, 10])

d = np.random.randint(0,20,size=(3,2))
print(d)
axis = 0#求所有列的和
>>>
[[16 16]
 [ 5  4]
 [ 4 15]]
array([25, 35])


d = np.random.randint(0,20,size=(3,2))
print(d)
axis = None#求所有元素的和
>>>
[[ 4 18]
 [ 3 10]
 [ 9  8]]
52

常用的數學函式

  • NumPy 提供了標準的三角函式:sin()、cos()、tan()
  • numpy.around(a,decimals) 函式返回指定數字的四捨五入值。
    • 引數說明:
      • a: 陣列
      • decimals: 舍入的小數位數。 預設值為0。 如果為負,整數將四捨五入到小數點左側的位置
d = np.random.randint(0,20,size=(3,2))
print(d)
np.around(d,decimals=-1)
>>>
[[10 12]
 [ 1 13]
 [16 19]]
array([[10, 10],
       [ 0, 10],
       [20, 20]])

14、常用的統計函式

  • numpy.amin() 和 numpy.amax(),用於計算陣列中的元素沿指定軸的最小、最大值。
  • numpy.ptp():計算陣列中元素最大值與最小值的差(最大值 - 最小值)。
  • numpy.median() 函式用於計算陣列 a 中元素的中位數(中值)
  • 標準差std():標準差是一組資料平均值分散程度的一種度量。[波動性]
    • 公式:std = sqrt(mean((x - x.mean())**2))
    • 如果陣列是 [1,2,3,4],則其平均值為 2.5。 因此,差的平方是 [2.25,0.25,0.25,2.25],並且其平均值的平方根除以 4,即 sqrt(5/4) ,結果為 1.1180339887498949。
  • 方差var():統計中的方差(樣本方差)是每個樣本值與全體樣本值的平均數之差的平方值的平均數,即 mean((x - x.mean())** 2)。換句話說,標準差是方差的平方根。