1. 程式人生 > >Numpy、matplotlib

Numpy、matplotlib

簡介

numpy - numeric python, 即數字化的python;python 支援的數值型別有整型、浮點型、布林型、和複數型;numpy支援更多的數值型別:

    1. `bool`:布林型別,1 個位元組,值為 True 或 False。

    2. `int`:整數型別,通常為 int64 或 int32 。

    3. `intc`:與 C 裡的 int 相同,通常為 int32 或 int64。

    4. `intp`:用於索引,通常為 int32 或 int64。

    5. `int8`:位元組(從 -128 到 127)  

       (tinyint  1位元組   -2 ^7 ~ 2^7-1   (-128~127))

    6. `int16`:整數(從 -32768 到 32767) 

       (smallint 2位元組 -2 ^15 ~ 2^15-1   (-32768~32765))

    7. `int32`:整數(從 -2147483648 到 2147483647) 

       (int 4位元組 -2 ^31~ 2^31-1   (-2147483648~2147483647))

    8. `int64`:整數(從 -9223372036854775808 到 9223372036854775807)

       (bigint  8位元組  -2 ^63 ~ 2^63-1)

    9. `uint8`:無符號整數(從 0 到 255) unsigned

    10. `uint16`:無符號整數(從 0 到 65535)

    11. `uint32`:無符號整數(從 0 到 4294967295)

    12. `uint64`:無符號整數(從 0 到 18446744073709551615)

    13. `float`:float64 的簡寫。

    14. `float16`:半精度浮點,5 位指數,10 位尾數

    15. `float32`:單精度浮點,8 位指數,23 位尾數

    16. `float64`:雙精度浮點,11 位指數,52 位尾數

    17. `complex`:complex128 的簡寫。

    18. `complex64`:複數,由兩個 32 位浮點表示。

    19. `complex128`:複數,由兩個 64 位浮點表示。

在 Numpy 中,上面提到的這些數值型別都被歸於 dtype(data-type) 物件的例項。

我們可以用 numpy.dtype(object, align, copy) 來指定數值型別。而在數組裡面,可以用 dtype= 引數。

Ndarray

numpy中最重要的一個形式叫陣列ndarray - n個維度(dimension)的陣列(array);

認識陣列
  1. ndarray 具有6個引數:shape、dtype、buffer、offset、strides(資料的步長)、order(以行或者列為主排列順序)

  2. ndarray陣列的屬性:

    ndim: 陣列的維度 nd1.ndim
    shape: 形狀(5, 4, 3) nd1.shape
    size: 陣列的總長度 nd1.size
    dtype: 檢視資料型別 nd1.dtype

建立陣列的方法:
  1. 使用ndarray方法建立三維陣列

    nd1 = np.ndarray(shape=(5, 4, 3), dtype=np.int64)

  2. 使用列表或者陣列建立矩陣

    nd2 = np.array(list(‘12345’))

  3. arange方法建立陣列, 在指定範圍內建立均勻間隔的數值

    numpy.arange(start, stop, step, dtype=None)
    nd3=np.arange(0,150,step=5,dtype=np.float32)
    將值倒過來:step=-1

  4. linespace方法建立陣列,在指定的範圍內返回指定數量的值,這些值的間隔是均勻的

    numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
    endpoint: 布林值, 如果為真,則最後一個樣本包含在序列內
    restep: 布林值,如果為真,返回間距

  5. ones方法建立全部值為1的多維陣列

    numpy.ones(shape, dtype=None, order=’C’)

  6. zeros 方法建立 全部值為0的多維陣列

    numpy.zeros(shape, dtype=None, order=’C’)

  7. full方法可以建立一個使用自定義的值,填滿整個陣列

    numpy.full(shape,fill_value=num)

  8. eye 方法建立多維維陣列,特點是k對角線上的值為1,其餘值為0

    numpy.eye(N, M=None, k=0, dtype=<type 'float'>)
    

    n是陣列的行數, m陣列的列數, k:對角線索引,預設0指主對角線,大於0往上平移,小於0往下平移

  9. 產生隨機的陣列

    np.random.randint(low=0, high=150, size=(5, 4))
    size 是一個元祖型別, low和high可以省略不寫

    np.random.random(size=(456, 730, 3))

  10. 元素的值呈現標準的正太分佈

    np.random.randn(10, 5)
    沒有固定的引數,沒多加一個引數,代表多增加一個維度

  11. 標準方差,元素的值滿足標準方差

    np.random.normal(loc=170, scale=100m, size=50)

    location:定位的值, scale:波動的幅度,size:資料的長度

  12. 產生的元素是隨機的,沒有範圍

    np.random.rand(d1, d2,,,dn)
    每一個引數,代表一個維度

  13. linspace與logspace

    linspace 是線性生成的,全閉區間

    nd6 = np.linspace(0,150,num=151)

    logspace是線性生成的,並且以什麼為底
    num:生成多少個數,base表示的是底數,預設是10為底
    np.log10(100)
    nd7 = np.logspace(0,150,num=151,base=np.e)
    np.logspace(0,150,num=151,base=np.pi)

  14. 構建對角矩陣

    np.diag(v, k=0)引數為列表即可
    v可以是一維或二維矩陣
    k小於0,斜線在矩陣的下方,大於0相反
    np.diag([1,2,3], k= 1)

  15. 檔案I/O建立陣列

    csv、dat是一種常用的資料格式化檔案型別;

    從檔案中讀取資料:

    numpy.genfromtxt()
    data1=np.genfromtxt('123.dat')
    
    data2=np.loadtxt('123.dat')
    
    data3=np.mafromtxt('123.dat')
    
    data4=np.ndfromtxt('123.dat')
    
    data5=np.recfromtxt('123.dat')
    

    向檔案中儲存資料:

    建立一個3 X 3 的二維陣列
    M = np.random.rand(3, 3)
    np.savetxt('123.dat', M)
    

    numpy中的原生檔案型別:以npy結尾結尾的檔名
    使用 numpy.save 與 numpy.load儲存和讀取資料:

    np.save('123.npy', M)
    np.load('123.npy')
    

    關於陣列的操作:

    ndarray.T 用於陣列的轉置, 與.transpose()
    
    ndarray.imag 用來輸出陣列元素的虛部
    
    ndarray.real 用來輸出陣列元素的虛部
    
    ndarray.itemsize 用來輸出一個數組元素所佔用的位元組數
    
    ndarray.nbytes用來輸出陣列的所有的元素所佔的總的位元組數
    
    ndarray.striders: 用來輸出每個維度中步進的位元組數
    
關於陣列的操作
  1. 改變資料型別:

    # 把陣列nd4的資料型別改成整型,不適用dtype屬性改變的預設資料型別
    nd4.astype(np.int)
    
  2. 重設陣列的形狀:

    reshape可以在不改變陣列資料的同時,改變陣列的形狀
    numpy.reshape() 等同於 ndarray.reshape()
    
    nd1 = np.random.randint(0, 150, size=(5, 4))
    
    # 把上面5行4列改成10行2列
    nd1.reshape((10,2))
    

    引數是元祖,改變前後要保證元素總數相等,也可以是單個值,可以是list或者元祖的形式

  3. 將陣列扁平化, 將任意形狀的陣列扁平化,變為1維陣列

    nd1.ravel()
    
  4. 陣列之間的級聯:

    np.concatenate()
    

    級聯的引數是列表: 一定要加中括號,或者小括號
    級聯的兩個表維度必須相同,形狀相似(同行同列、同行不同列、同列不同行),水平及聯時行要相同,垂直級聯時列要相同
    級聯的方向,預設為0, 表示垂直相連,表示x軸的事情
    1表示水平相連,表示y軸的事情

    可通過axis改變級聯的方向,預設為0

    np.concatenate((nd2, nd3), axis=1)
    

    把貓和狗的圖片進行合併,級聯即合併,切片保證和狗的行列相同

    cat1 = cat[50:350,100:413]
    

    垂直級聯
    cat_dog = np.concatenate((cat1,dog))
    水平級聯
    cat_dog = np.concatenate((cat1,dog),axis=1)

    級聯的方式2:

    函式:填入的引數必須被小括號,或者中括號包著,這兩個函式的值也是一個list或者tuple
    hstack(): 水平級聯  
    vstack(): 垂直級聯
    
    vertical垂直的  horizontal水平的 stack層積
    
        dc=np.hstack((cat1,dog))
        plt.imshow(dc)
    
  5. 分割陣列:

    numpy.split(array, [index1, index2,…], axis)

    axis預設值是0, 表示垂直級聯

    注意: 列表中的引數,第一個值代表 0-index1,第二個index1-index2,還有
    index: , 即兩個值可以把一個數組,切成三份

    將貓水平切成三份:
    cat1, cat2, cat3 = np.split(cat, [100, 200])

    plt.imshow(cat1)
    plt.show()
    plt.imshow(cat2)
    plt.show() show是用於幫助圖形顯示的
    plt.imshow(cat3)
    也可以使用函式vsplit
    將貓垂直切成三份,後面加上引數axis=1

  6. 複製陣列:

    cat2 = cat.copy()
    檢視元素在系統中的編號:id(cat2)
    display(id(cat2),id(cat))

  7. 求和:np.sum

    ndarray.sum(axis), axis不寫則為所有元素的求和,為0表示列求和, 1表示行求和

    one = np.ones((5, 4))

    求4維矩陣中最後兩維的和:

    one_ = np.ones((3,3,3,3))
    
    #axis的值可以是一個元組,最後一維可以用-1來表示,-2可以用
    來表示倒數第二維
    one_.sum(axis=(-1,-2))
    
  8. 求陣列的最大最小值:np.max/np.min

    cat.max(axis=0)
    cat.min()

  9. 陣列的平均值:

    cat.mean(axis=0)
    cat5 = cat.mean(axis=2)

  10. 去掉三維矩陣中的第三維:

    cat3 = cat.max(axis=2)
    
    cond = nd1.argmax()
    nd2 = nd1.reshape(20)
    nd2[cond]
    
  11. argwhere where相當於mysql中的where條件

    index = np.argwhere(nd1<134)
    nd1[index[:,0],index[:,1]]
    
  12. 移動陣列的軸:

    二維矩陣行變列

    numpy.moveaxis(a, source, destination)
        a:陣列。
        source:要移動的軸的原始位置。
        destination:要移動的軸的目標位置。
    

    nd1 = np.array([[1,2,3],[1,2,3],[1,2,3]])
    np.moveaxis(nd1,0,1)

  13. 軸交換:

    numpy.swapaxes(a, axis1, axis2)
    a:陣列。
    axis1:需要交換的軸 1 位置。
    axis2:需要與軸 1 交換位置的軸 1 位置。
    
    nd1 = np.random.randint(0,100,size=(5,4,3))
    np.swapaxes(nd1,0,2)
    

    transpose 類似於矩陣的轉置,它可以將 2 維陣列的水平軸和垂直交換。其方法如下:

    numpy.transpose(a, axes=None)
    
    a:陣列。
    axis:該值預設為 none,表示轉置。如果有值,那麼則按照值替換軸。
    np.transpose(nd1)
    
  14. 陣列迴圈:

    # tile迴圈,依賴是行,把每行中的資料迴圈N次
    np.title(nd, 3)
    
    # repeat迴圈會先降維,再進行迴圈 迴圈每一個元素
    np.repeat(nd, 3)
    
    # 矩陣每個基本元素都執行運算
    nd1 + 3
    np.add(nd1, 10)
    
    np.multiply(nd1, 10)
    np.dot(nd1, 10)
    
  15. 矩陣的乘積

    np.dot(nd1, nd2)
    要確保第二個矩陣的行要等於第一個矩陣的列

    三維乘一維:

    nd3 = np.random.randint(0, 10, size=(5,4,3))
    nd4 = np.random.randint(0, 10, size=3)
    np.dot(nd3, nd4)
    

    三維乘二維:

    nd3 = np.random.randint(0, 10, size=(5, 4, 3))
    nd4 = np.random.randint(0, 10, size=(3,4))
    np.dot(nd3, nd4)
    
  16. ndarray廣播機制:

    規則1: 為缺失的維度補1
    規則2:假定缺失元素用已有值填充
    # 兩行三列
    nd1 = np.ones((2,3))
    # 一行三列
    nd2 = np.arange(3)
    # 列相加
    nd1 + nd2
    np.add(nd1, nd2)
    array([[1., 2., 3.],
           [1., 2., 3.]])
    
  17. 陣列的排序:

    nd = np.random.randint(0, 150, size=10)

    氣泡排序 一維矩陣和列表一樣, 迴圈出每一個元素,並且讓該元素,與其它所有元素相比

    for i in range(nd.size):
        for j in range(nd.size-1):
            if nd[i] < nd[j]:
                nd[i],nd[j] = nd[j], nd[i]
    

    用一層迴圈
    argmin, 封裝成函式

    def sort_nd(nd):
        for i in range(nd.size):
            #  為什麼+i, 不加上i索引會亂
            min_index = nd[i:].argmin() + i
            nd[i], nd[min_index] = nd[min_index], nd[i]
    
    sort_nd(nd1)
    

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

    np.sort()不改變原陣列
    ndarray.sort()本地處理,不佔用空間,但改變元素組
    
    nd2 = np.random.randint(0, 10, size=10)
    
    np.sort(nd2)
    

    對原陣列產生了影響

    nd2.sort()
    
  18. 部分排序:

    np.partition(a,k)
    有的時候我們不是對全部資料感興趣,我們可能只對最小或最大的一部分感興趣。

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

    np.partition(nd3, -5)[-5:]
    np.partition(nd3, 5)[:5]
    np.sort(np.partition(nd3, 5)[:5])
    

matplotlib

matplotlib的使用:

import matplotlib.pyplot as plt

# 讀取圖片 png格式RGB取值範圍0-1 jpg是0-255
fish = plt.imread('123.png/jpg')
# 列印圖片
plt.imshow(fish)

# 檢視圖片的大小, 圖片是三維陣列,第三維表示RGB的值,前兩維表示行和列的值,分別對應y和x軸, 座標原點位於螢幕的左上角
fish.shape

顛倒圖片:
上下顛倒:保持列不變,二位陣列代表y軸, 所有的行取反,一行代表一個二維陣列,一列代表一個一維陣列
    fish1 = fish[::-1, :]
    plt.imshow(fish1)
左右顛倒: 保持行不變
    fish1 = fish[:, ::-1]
    plt.imshow(fish1)

# 將RGB的值進行顛倒
fish2 = fish1[:,:, ::-1]

把魚頭換成狗頭:

    fish = plt.imread('fish.png')
    dog = plt.imread('dog.jpg')
    plt.imshow(fish[50:150,70:190])
    plt.imshow(dog[50:150,70:190])
    #fish是png           #dog是jpg
    dogface_fish=fish[50:150,70:190] = dog[50:150, 70:190].astype(np.float32)/255

    plt.imshow(fish)


    #生成一張隨機的圖片,然後替換到魚的頭部
    fish[50:150,70:190]  = np.random.randint(0,255,size=(100,120,3)).astype(np.float32)/255

將彩色圖片列印成黑白:plt.imshow(cat2, cmap=’gray’)