Python進階—Numpy

2022-01-09 13:00:22

Numpy 再來一遍


配合 機器學習食用更佳。

import numpy as np

一、Numpy的屬性

  • ndim 維度
  • shape 形狀
  • dtype 型別
  • size 大小
array = np.array([[1,2,3],
                 [4,5,6]])
print(array)
[[1 2 3]
 [4 5 6]]
print(array.ndim) # 維度
2
print(array.shape) # 形狀
(2, 3)
print(array.dtype) # 元素型別
int64
print(array.size) # 大小
6

二、建立array

  • 指定資料屬性
  • 建立一維資料、二維資料
  • zeros 全0、 ones 全1、 empty 全接近於0、 arange 等差一維陣列
  • reshape 改變矩陣形狀
a = np.array([1,2,3],dtype=np.int32) # 指定資料型別
print(a)
[1 2 3]
b = np.array([1,2,3],dtype=np.float) # 指定資料型別 
print(b.dtype)
float64
c = np.array([1,2,3]) # 一維資料
print(c)
[1 2 3]
d = np.array([[1,2,3],[4,5,6]]) # 二維資料
print(d)
[[1 2 3]
 [4 5 6]]
zero = np.zeros((2,3)) # 生成2行3列的全0矩陣
print(zero)
[[0. 0. 0.]
 [0. 0. 0.]]
one = np.ones((3,4)) # 生成3行4列的全1矩陣
print(one)
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
empty = np.empty((3,3)) # 生成3行3列的全都接近於0(不等於0)的矩陣
print(empty)
[[6.92430951e-310 4.67278860e-310 6.92414190e-310]
 [6.92414190e-310 6.92414190e-310 6.92414190e-310]
 [6.92414190e-310 6.92414190e-310 3.95252517e-322]]
e = np.arange(5) 
print(e)
[0 1 2 3 4]
f = np.arange(4,12)
print(f)
[ 4  5  6  7  8  9 10 11]
g = np.arange(4,12,2)
print(g)
[ 4  6  8 10]
h = np.arange(8).reshape(4,2) # 重新定義矩陣的形狀
print(h)
[[0 1]
 [2 3]
 [4 5]
 [6 7]]

三、Numpy的運算

  • ‘+ - * / // ** % >’
  • np.dot(arr1,arr2) == arr1.dot(arr2) 矩陣乘法
  • arr1.T == np.transpose(arr1)
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])
print(arr1,arr2)
[1 2 3] [4 5 6]
print(arr1+arr2)
[5 7 9]
print(arr1-arr2)
[-3 -3 -3]
print(arr1*arr2)
[ 4 10 18]
print(arr1/arr2)
[0.25 0.4  0.5 ]
print(arr1**arr2)
[  1  32 729]
print(arr1 // arr2)
[0 0 0]
print(arr1 % arr2)
[1 2 3]
print(arr1 + 1)
[2 3 4]
print(arr1 * 3)
[3 6 9]
print(arr1 > 3)
[False False False]
arr3 = np.arange(6).reshape(3,2)
arr4 = np.arange(6).reshape(2,3)
np.dot(arr3,arr4) # 矩陣乘法
array([[ 3,  4,  5],
       [ 9, 14, 19],
       [15, 24, 33]])
arr3.dot(arr4)
array([[ 3,  4,  5],
       [ 9, 14, 19],
       [15, 24, 33]])
print(arr3.T) # 矩陣轉置
[[0 2 4]
 [1 3 5]]
print(arr3)
[[0 1]
 [2 3]
 [4 5]]
print(np.transpose(arr3))
[[0 2 4]
 [1 3 5]]

四、亂數生成及矩陣的統計

  • np.random.random 0-1的亂數
  • np.random.normal 符合正態分佈的亂數
  • np.random.randint(0,10,size=()) 生成從0到10的size形狀的隨機整數
  • np.sum() 求和、np.mean() 求平均值 np.max() 求最大值、 np.min() 求最小值
  • np.sort() 排序、np.sqrt() 開方、 np.median() 求中位數、 axis=0 0行1列
  • np.argmin() 求最小值的下標、np.argmax() 求最大值下標
arr1 = np.random.random((2,2)) # 生成2行2列從0到1的亂數
print(arr1)
[[0.70322893 0.62660424]
 [0.10822154 0.70288038]]
arr2 = np.random.normal(size=(3,3)) # 生成3行3列的符合標準正態分佈的亂數
print(arr2)
[[ 0.27050106  0.66089326  0.05234379]
 [ 0.81437662 -0.41467658  2.49832908]
 [-0.17560416  0.42175065 -1.02400744]]
arr3 = np.random.randint(0,10,size=(4,3)) # 生成4行3列的從0到10的隨機整數
print(arr3)
[[4 1 9]
 [8 7 9]
 [9 1 9]
 [5 0 9]]
np.sum(arr1) # 求和 == arr1.sum()
2.1409350945823276
np.min(arr1) # 求最小值 == arr1.min()
0.10822154146948515
np.max(arr1) # 求最大值 == arr1.max()
0.7032289271352641
np.sum(arr1,axis=0) # 對列求和
array([0.81145047, 1.32948463])
np.sum(arr1,axis=1) # 對行求和
array([1.32983317, 0.81110192])
np.argmin(arr1) # 求最小值的索引 從0開始
2
np.argmax(arr1) # 求最大值的索引
0
np.mean(arr1) # 求平均值 == np.sum(arr1) / arr1.size == arr1.mean()
0.5352337736455819
np.median(arr1) # 求中位數
0.6647423129887893
np.sqrt(arr1) # 開方 == arr1 ** 0.5
array([[ True,  True],
       [ True,  True]])
np.sort(arr1) # 排序 每一行是升序
array([[0.62660424, 0.70322893],
       [0.10822154, 0.70288038]])
np.clip(arr1,0.5,0.6) # 小於0.5變成0.5 大於0.6就變成0.6
array([[0.6, 0.6],
       [0.5, 0.6]])

五、Numpy索引

  • 索引arr1[1,2] == arr1[1][2]
  • 切片 [:,:] 逗號前面代表行,後面代表列
  • 遍歷行、遍歷列、遍歷元素
print(arr1)
[[0.62660424 0.70322893]
 [0.10822154 0.70288038]]
print(arr1[0]) 
[0.62660424 0.70322893]
print(arr1[0][1]) == print(arr1[0,1])  
0.7032289271352641
print(arr1[:,1]) # 第二列
[0.70322893 0.70288038]
print(arr1[1,1])
0.7028803828361643
for i in arr1: # 迭代行
    print(i)
[0.62660424 0.70322893]
[0.10822154 0.70288038]
for i in arr1.T: # 迭代列
    print(i)
[0.62660424 0.10822154]
[0.70322893 0.70288038]
arr1.reshape(1,-1)
array([[0.62660424, 0.70322893, 0.10822154, 0.70288038]])
for i in arr1.flat: # 迭代所有元素
    print(i)
0.6266042431414143
0.7032289271352641
0.10822154146948515
0.7028803828361643

六、合併

  • 一維資料合併 np.vstack 垂直合併、 np.hstack 水平合併
  • 多維資料合併 np.concatenate((arr1,arr2)) # 預設垂直合併、np.concatenate((arr1,arr2),axis=1) # 水平合併
  • 增加一個新的維度np.newaxis
  • 變成nd資料 np.atleast_nd n可以為1、2、3、4…
arr1 = np.arange(3)
arr2 = np.arange(3)
print(arr1,arr2)
[0 1 2] [0 1 2]
np.vstack((arr1,arr2)) # 垂直合併
array([[0, 1, 2],
       [0, 1, 2]])
np.hstack((arr1,arr2)) # 水平合併
array([0, 1, 2, 0, 1, 2])
np.concatenate((arr1,arr2)) 
array([0, 1, 2, 0, 1, 2])
arr3 = np.arange(4).reshape(2,2) 
np.concatenate((arr3,arr3))
array([[0, 1],
       [2, 3],
       [0, 1],
       [2, 3]])
np.concatenate((arr3,arr3),axis=1)  # 該方法不能對1維資料進行垂直合併
array([[0, 1, 0, 1],
       [2, 3, 2, 3]])
arr1.T # 一維資料不能轉置
array([0, 1, 2])
arr1[np.newaxis,:] # 在行這個維度上增加一個維
array([[0, 1, 2]])
arr1[:,np.newaxis]
array([[0],
       [1],
       [2]])
np.atleast_2d(arr1)
array([[0, 1, 2]])

七、分割

  • 等分 np.split 0行1列
  • 不等分 np.array_split 0行1列
  • 垂直分np.hsplit、水平分np.vsplit
arr1 = np.arange(12).reshape(3,4)
print(arr1)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
np.split(arr1,2,axis=1) # 豎直方向分割,平均為2份 
[array([[0, 1],
        [4, 5],
        [8, 9]]), array([[ 2,  3],
        [ 6,  7],
        [10, 11]])]
np.split(arr1,3,axis=0) # 水平方向分割,平均為3份
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]
np.split(arr1,3,axis=1) # 豎直方向分割,平均為3份
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/opt/conda/lib/python3.6/site-packages/numpy/lib/shape_base.py in split(ary, indices_or_sections, axis)
    866     try:
--> 867         len(indices_or_sections)
    868     except TypeError:


TypeError: object of type 'int' has no len()


During handling of the above exception, another exception occurred:


ValueError                                Traceback (most recent call last)

<ipython-input-112-2e738d9e1da7> in <module>
----> 1 np.split(arr1,3,axis=1) # 水平方向分割,平均為3份


<__array_function__ internals> in split(*args, **kwargs)


/opt/conda/lib/python3.6/site-packages/numpy/lib/shape_base.py in split(ary, indices_or_sections, axis)
    871         if N % sections:
    872             raise ValueError(
--> 873                 'array split does not result in an equal division')
    874     return array_split(ary, indices_or_sections, axis)
    875 


ValueError: array split does not result in an equal division
np.array_split(arr1,3,axis=1) # 豎直方向分割,不等分為3份
[array([[0, 1],
        [4, 5],
        [8, 9]]), array([[ 2],
        [ 6],
        [10]]), array([[ 3],
        [ 7],
        [11]])]
np.vsplit(arr1,3) # == np.split(arr1,3,axis=0) # 水平方向分割,平均為3份
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]
np.hsplit(arr1,2)# == np.split(arr1,2,axis=1) # 豎直方向分割,平均為2份 
[array([[0, 1],
        [4, 5],
        [8, 9]]), array([[ 2,  3],
        [ 6,  7],
        [10, 11]])]

八、深淺拷貝

  • Python是參照傳遞,預設記憶體共用
  • arr1.copy() 深拷貝 完全獨立開
arr1
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
arr2 = arr1
arr2[0] = 0
arr2
array([[ 0,  0,  0,  0],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
arr1
array([[ 0,  0,  0,  0],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
arr3 = arr1.copy() # 深拷貝
arr3[0] = 1
arr3
array([[ 1,  1,  1,  1],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
arr1
array([[ 0,  0,  0,  0],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])