Python NumPy學習總結

戰爭熱誠發表於2018-10-12

一、NumPy簡介

  其官網是:http://www.numpy.org/

  NumPy是Python語言的一個擴充程式庫。支援高階大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫。Numpy內部解除了CPython的GIL(全域性直譯器鎖),執行效率極好,是大量機器學習框架的基礎庫!

  關於GIL請參考部落格:http://www.cnblogs.com/wj-1314/p/9056555.html

NumPy的全名為Numeric Python,是一個開源的Python科學計算庫,它包括:

  • 一個強大的N維陣列物件ndrray;
  • 比較成熟的(廣播)函式庫;
  • 用於整合C/C++和Fortran程式碼的工具包;
  • 實用的線性代數、傅立葉變換和隨機數生成函式

 NumPy的優點:

  • 對於同樣的數值計算任務,使用NumPy要比直接編寫Python程式碼便捷得多;
  • NumPy中的陣列的儲存效率和輸入輸出效能均遠遠優於Python中等價的基本資料結構,且其能夠提升的效能是與陣列中的元素成比例的;
  • NumPy的大部分程式碼都是用C語言寫的,其底層演算法在設計時就有著優異的效能,這使得NumPy比純Python程式碼高效得多

         當然,NumPy也有其不足之處,由於NumPy使用記憶體對映檔案以達到最優的資料讀寫效能,而記憶體的大小限制了其對TB級大檔案的處理;此外,NumPy陣列的通用性不及Python提供的list容器。因此,在科學計算之外的領域,NumPy的優勢也就不那麼明顯。

   關於Python Numpy矩陣的用法總結請參考博文:https://www.cnblogs.com/wj-1314/p/10244807.html

二,numpy儲存二進位制檔案(.npy/.npz)

  ndarray物件可以儲存到磁碟檔案並從磁碟檔案載入,可用的IO功能有:

  •   load()和save() 函式處理Numpy 二進位制檔案(帶npy副檔名)。
  •   loadtxt() 和savetxt() 函式處理正常的文字檔案。

  Numpy為ndarray物件引入了一個簡單的檔案格式,這個npy檔案在磁碟檔案中,儲存重建ndarray所需的資料,圖形,dtype和其他資訊,以便正確獲取陣列,即使該檔案在具有不同架構的一臺機器上。

   numpy.load和numpy.save函式式以Numpy專用的二進位制型別儲存資料,這兩個函式會自動處理元素型別和shape等資訊,使用它們讀寫陣列就方便多了,但是numpy.save輸出的檔案很難和其他語言編寫的程式讀入。

1,numpy.save

  儲存一個陣列到一個二進位制的檔案中,儲存格式是.npy

  引數介紹:

numpy.save(file, arr, allow_pickle=True, fix_imports=True)

file:檔名/檔案路徑
arr:要儲存的陣列
allow_pickle:布林值,允許使用Python pickles儲存物件陣列(可選引數,預設即可)
fix_imports:為了方便Pyhton2中讀取Python3儲存的資料(可選引數,預設即可)

  舉例說明:

>>> import numpy as np 
#生成資料 
>>> x=np.arange(10) 
>>> x 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
 
#資料儲存 
>>> np.save('save_x',x) 
 
#讀取儲存的資料 
>>> np.load('save_x.npy') 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 

  

2,numpy.savez

  這個同樣是儲存陣列到一個二進位制的檔案中,但是厲害的是,它可以儲存多個陣列到同一個檔案中,儲存格式為.npz,它們其實就是多個前面np.save的儲存的npy,再通過打包(未壓縮)的方式把這些檔案歸到一個檔案上,不行你再去解壓npz檔案就知道自己儲存的是多個npy。

  引數介紹:

numpy.savez(file, *args, **kwds)

file:檔名/檔案路徑
*args:要儲存的陣列,可以寫多個,如果沒有給陣列指定Key,Numpy將預設從'arr_0','arr_1'的方式命名
kwds:(可選引數,預設即可)

  舉例說明:

>>> import numpy as np 
#生成資料 
>>> x=np.arange(10) 
>>> x 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> y=np.sin(x) 
>>> y 
array([ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 , 
       -0.95892427, -0.2794155 ,  0.6569866 ,  0.98935825,  0.41211849]) 
        
#資料儲存 
>>> np.save('save_xy',x,y) 
 
#讀取儲存的資料 
>>> npzfile=np.load('save_xy.npz') 
>>> npzfile  #是一個物件,無法讀取 
<numpy.lib.npyio.NpzFile object at 0x7f63ce4c8860> 
 
#按照組數預設的key進行訪問 
>>> npzfile['arr_0'] 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> npzfile['arr_1'] 
array([ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 , 
       -0.95892427, -0.2794155 ,  0.6569866 ,  0.98935825,  0.41211849]) 

  更加神奇的是,我們可以不適用Numpy給陣列的key,而是自己給陣列有意義的key,這樣就可以不用去猜測自己載入資料是否是自己需要的。

#資料儲存 
>>> np.savez('newsave_xy',x=x,y=y) 
 
#讀取儲存的資料 
>>> npzfile=np.load('newsave_xy.npz') 
 
#按照儲存時設定組數key進行訪問 
>>> npzfile['x'] 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> npzfile['y'] 
array([ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 , 
       -0.95892427, -0.2794155 ,  0.6569866 ,  0.98935825,  0.41211849]) 

  在深度學習中,我們儲存了訓練集,驗證集,測試集,還包括它們的標籤,用這個方式儲存起來,要載入什麼有什麼,檔案數量大大減少,也不會到處改檔名。

3,savetxt()

  以簡單文字檔案格式儲存和獲取陣列資料,通過savetxt()和loadtxt()函式來完成的。

import numpy as np

a = np.array([1,2,3,4,5])
np.savetxt('out.txt',a)
b = np.loadtxt('out.txt')
print(b)
# [1. 2. 3. 4. 5.]

   savetxt()和loadtxt()函式接受附加的可選引數,例如頁首,頁尾和分隔符。

4,csv檔案轉化為npy格式

  下面有一個csv檔案的資料,我想將其轉化為npy格式,資料內容如下:

cut,flute_1,flute_2,flute_3
1,31.41635516,19.48369225,21.74806264
2,34.8927704,23.473047,24.92595987
3,38.10284657,27.17286849,27.89865916
4,41.06102301,30.59930868,30.67784802
5,43.78119133,33.76786983,33.27472071
6,46.27671037,36.69342355,35.6999933
7,48.56042098,39.39022937,37.96391852
8,50.64466037,41.87195302,40.07630017
9,52.54127629,44.15168423,42.04650728

  首先,資料是有索引,序列的,所以我們讀取的時候要注意,轉化程式碼如下:

import pandas as pd
import numpy as np

file1 = 'Train_A_wear.csv'
data1 = pd.read_csv(file1,header=0,index_col=0)

np.save('train_A_wear.npy',data1.values)
data_A_wear = np.load('trainA_wear.npy') 

  

三、陣列ndarray

  Numpy中定義的最重要的物件是成為ndarray的N維陣列型別。它描述相同型別的元素集合。可以使用基於零的索引訪問集合中的專案。

  大部分的陣列操作僅僅是修改後設資料部分,而不改變其底層的實際資料。陣列的維數稱為秩,簡單來說就是如果你需要獲取陣列中一個特定元素所需的座標數,如a是一個2×3×4的矩陣,你索引其中的一個元素必須給定三個座標a[x,y,z],故它的維數就是3。

  我們可以直接將陣列看作一種新的資料型別,就像list、tuple、dict一樣,但陣列中所有元素的型別必須是一致的,Python支援的資料型別有整型、浮點型以及複數型,但這些型別不足以滿足科學計算的需求,因此NumPy中新增了許多其他的資料型別,如bool、inti、int64、float32、complex64等。同時,它也有許多其特有的屬性和方法。

3.1   常用ndarray屬性:

  • dtype        描述陣列元素的型別
  • shape       以tuple表示的陣列形狀
  • ndim         陣列的維度
  • size           陣列中元素的個數
  • itemsize    陣列中的元素在記憶體所佔位元組數
  • T               陣列的轉置
  • flat            返回一個陣列的迭代器,對flat賦值將導致整個陣列的元素被覆蓋
  • real/imag  給出複數陣列的實部/虛部
  • nbytes      陣列佔用的儲存空間
import numpy as np

# 建立簡單的列表
a = [1,2,3,4,5,6]

# 講列表轉換為陣列
b = np.array(a)

# Numpy檢視陣列屬性
print(b.size)
#6

# 陣列形狀
print(b.shape)
# (6,)

# 陣列維度
print(b.ndim)
# 1

# 陣列元素型別
print(b.dtype)
# int32

 

import numpy as np

a = np.array([1,2,3])
print(a)
# [1 2 3]

# 多於一個維度
a = np.array([[1,  2],  [3,  4]])
print(a)
# [[1 2]
#  [3 4]]

# 最小維度
a = np.array([1,  2,  3,4,5], ndmin =  2)
print(a)
# [[1 2 3 4 5]]

# dtype 引數
a = np.array([1,  2,  3], dtype = complex)
print(a)
# [1.+0.j 2.+0.j 3.+0.j]

   ndarray 物件由計算機記憶體中的一維連續區域組成,帶有將每個元素對映到記憶體塊中某個位置的索引方案。 記憶體塊以按行(C 風格)或按列(FORTRAN 或 MatLab 風格)的方式儲存元素。

3.2  常用ndarray方法

  • reshape(…)                          返回一個給定shape的陣列的副本
  • resize(…)                              返回給定shape的陣列,原陣列shape發生改變
  • flatten()/ravel()                      返回展平陣列,原陣列不改變
  • astype(dtype)                        返回指定元素型別的陣列副本
  • fill()                                        將陣列元素全部設定為一個標量值
  • sum/Prod()                            計算所有陣列元素的和/積
  • mean()/var()/std()                  返回陣列元素的均值/方差/標準差
  • max()/min()/ptp()/median()    返回陣列元素的最大值/最小值/取值範圍/中位數
  • argmax()/argmin()                  返回最大值/最小值的索引
  • sort()                                      對陣列進行排序,axis指定排序的軸;kind指定排序演算法,預設是快速排序
  • view()/copy()                          view創造一個新的陣列物件指向同一資料;copy是深複製
  • tolist()                                     將陣列完全轉為列表,注意與直接使用list(array)的區別
  • compress()                             返回滿足條件的元素構成的陣列

numpy.reshape:

import numpy as np
a = np.arange(8)
print('原始陣列:')
print(a)
print('\n')

b = a.reshape(4,2)
print('修改後的陣列:')
print(b)

'''結果
原始陣列:
[0 1 2 3 4 5 6 7]


修改後的陣列:
[[0 1]
 [2 3]
 [4 5]
 [6 7]]
'''

 numpy.ndarray.flatten:

import numpy as np
a = np.arange(8).reshape(2,4)

print('原陣列:')
print(a)
print('\n')
# default is column-major

print('展開的陣列:')
print(a.flatten())
print('\n')

print('以 F 風格順序展開的陣列:')
print(a.flatten(order = 'F'))
'''結果:
原陣列:
[[0 1 2 3]
 [4 5 6 7]]


展開的陣列:
[0 1 2 3 4 5 6 7]


以 F 風格順序展開的陣列:
[0 4 1 5 2 6 3 7]
'''

 numpy.ravel:

import numpy as np
a = np.arange(8).reshape(2,4)

print('原陣列:')
print(a)
print('\n')

print('呼叫 ravel 函式之後:')
print(a.ravel())
print('\n')

print('以 F 風格順序呼叫 ravel 函式之後:')
print(a.ravel(order = 'F'))
'''結果:
原陣列:
[[0 1 2 3]
 [4 5 6 7]]


呼叫 ravel 函式之後:
[0 1 2 3 4 5 6 7]


以 F 風格順序呼叫 ravel 函式之後:
[0 4 1 5 2 6 3 7]'''

 

3.3 陣列的建立

  numpy中使用array()函式建立陣列,array的首個引數一定是一個序列,可以是元組也可以是列表。

3.3.1  一維陣列的建立

  可以使用numpy中的arange()函式建立一維有序陣列,它是內建函式range的擴充套件版。

In [1]: import numpy as np

In [2]: ls1 = range(10)

In [3]: list(ls1)

Out[3]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [4]: type(ls1)

Out[4]: range

In [5]: ls2 = np.arange(10)

In [6]: list(ls2)

Out[6]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [7]: type(ls2)

Out[7]: numpy.ndarray

   通過arange生成的序列就不是簡簡單單的列表型別了,而是一個一維陣列。

如果一維陣列不是一個規律的有序元素,而是人為的輸入,就需要array()函式建立了。

In [8]: arr1 = np.array((1,20,13,28,22))

In [9]: arr1

Out[9]: array([ 1, 20, 13, 28, 22])

In [10]: type(arr1)

Out[10]: numpy.ndarray

   上面是由元組序列構成的一維陣列。

In [11]: arr2 = np.array([1,1,2,3,5,8,13,21])    

In [12]: arr2

Out[12]: array([ 1,  1,  2,  3,  5,  8, 13, 21])

In [13]: type(arr2)

Out[13]: numpy.ndarray

   上面是由列表序列構成的一維陣列。

3.3.2  二維陣列的建立

  二維陣列的建立,其實在就是列表套列表或元組套元組。

In [14]: arr3 = np.array(((1,1,2,3),(5,8,13,21),(34,55,89,144)))

In [15]: arr3

Out[15]:

array([[  1,   1,   2,   3],

[  5,   8,  13,  21],

[ 34,  55,  89, 144]])

   上面使用元組套元組的方式。

In [16]: arr4 = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

In [17]: arr4

Out[17]:

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

[ 5,  6,  7,  8],

[ 9, 10, 11, 12]])

   上面使用列表套列表的方式。

  對於高維陣列在將來的資料分析中用的比較少,這裡關於高維陣列的建立就不贅述了,構建方法仍然是套的方式。

   上面所介紹的都是人為設定的一維、二維或高維陣列,numpy中也提供了幾種特殊的陣列,它們是:

In [18]: np.ones(3)  #返回一維元素全為1的陣列

Out[18]: array([ 1.,  1.,  1.])

In [19]: np.ones([3,4])  #返回元素全為1的3×4二維陣列

Out[19]:

array([[ 1.,  1.,  1.,  1.],

[ 1.,  1.,  1.,  1.],

[ 1.,  1.,  1.,  1.]])

 
In [20]: np.zeros(3) #返回一維元素全為0的陣列

Out[20]: array([ 0.,  0.,  0.])

In [21]: np.zeros([3,4]) #返回元素全為0的3×4二維陣列

Out[21]:

array([[ 0.,  0.,  0.,  0.],

[ 0.,  0.,  0.,  0.],

[ 0.,  0.,  0.,  0.]])

In [22]: np.empty(3) #返回一維空陣列

Out[22]: array([ 0.,  0.,  0.])

In [23]: np.empty([3,4]) #返回3×4二維空陣列

Out[23]:

array([[ 0.,  0.,  0.,  0.],

[ 0.,  0.,  0.,  0.],

[ 0.,  0.,  0.,  0.]])

3.3.3  ones函式

  返回特定大小,以1填充的新陣列

>>> import numpy as np
>>> a=np.ones(3);a
array([ 1.,  1.,  1.])
>>> b=np.ones((3,2));b
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])

3.3.4  zeros函式

  返回特定大小,以0填充的新陣列。

官方庫的解釋:

def zeros(shape, dtype=None, order='C'): # real signature unknown; restored from __doc__
    """
    zeros(shape, dtype=float, order='C')
    
        Return a new array of given shape and type, filled with zeros.
    
        Parameters
        ----------
        shape : int or tuple of ints
            Shape of the new array, e.g., ``(2, 3)`` or ``2``.
        dtype : data-type, optional
            The desired data-type for the array, e.g., `numpy.int8`.  Default is
            `numpy.float64`.
        order : {'C', 'F'}, optional, default: 'C'
            Whether to store multi-dimensional data in row-major
            (C-style) or column-major (Fortran-style) order in
            memory.
    
        Returns
        -------
        out : ndarray
            Array of zeros with the given shape, dtype, and order.
    
        See Also
        --------
        zeros_like : Return an array of zeros with shape and type of input.
        empty : Return a new uninitialized array.
        ones : Return a new array setting values to one.
        full : Return a new array of given shape filled with value.
    
        Examples
        --------
        >>> np.zeros(5)
        array([ 0.,  0.,  0.,  0.,  0.])
    
        >>> np.zeros((5,), dtype=int)
        array([0, 0, 0, 0, 0])
    
        >>> np.zeros((2, 1))
        array([[ 0.],
               [ 0.]])
    
        >>> s = (2,2)
        >>> np.zeros(s)
        array([[ 0.,  0.],
               [ 0.,  0.]])
    
        >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
        array([(0, 0), (0, 0)],
              dtype=[('x', '<i4'), ('y', '<i4')])
    """
    pass

 

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

引數:

shape:int或ints序列
    新陣列的形狀,例如(2,3 )或2。
dtype:資料型別,可選
    陣列的所需資料型別,例如numpy.int8。預設值為 numpy.float64。
order:{'C','F'},可選
是否在儲存器中以C或Fortran連續(按行或列方式)儲存多維資料。

 返回:

out:ndarray
    具有給定形狀,資料型別和順序的零陣列。

 

>>> c=np.zeros(3)
>>> c
array([ 0.,  0.,  0.])
>>> d=np.zeros((2,3));d      
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]]) 

#d=np.zeros(2,3)會報錯,d=np.zeros(3,dtype=int)來改變預設的資料型別

3.3.5  eye&identity函式

  eye()函式用於生成指定行數的單位矩陣

>>> e=np.eye(3);e
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> e=np.eye(3,2);e
array([[ 1.,  0.],
       [ 0.,  1.],
       [ 0.,  0.]])
>>> e=np.eye(3,1);e
array([[ 1.],
       [ 0.],
       [ 0.]])
>>> e=np.eye(3,3);e
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
>>> e=np.eye(3,3,1);e
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  0.,  0.]])
e=np.eye(3,3,2);e
array([[ 0.,  0.,  1.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>> e=np.eye(3,3,3);e
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>> e=np.eye(3,3,4);e
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
>>> p=np.identity(4);p
array([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])
>>> p=np.identity(4,3);p  #會報錯
>>> p=np.identity((4,3));p  #會報錯

 3.3.6 empty函式

  它建立指定形狀和dtype的未初始化陣列。它使用以下建構函式:

numpy.empty(shape, dtype = float, order = 'C')

   注意:陣列為隨機值,因為他們未初始化。

import numpy as np
x = np.empty([3,2], dtype =  int)
print(x)
# [[1762    0]
#  [   0    0]
#  [   0    0]]

 

>>> a=np.empty(3);a
array([  1.60091154e-163,   1.12069303e-258,   3.23790862e-318])
>>> a=np.empty((3,3));a
array([[  1.57741456e-284,   1.57680914e-284,   1.56735002e-163],
       [  1.56205068e-163,   1.62511438e-163,   1.21880041e+171],
       [  1.57757869e-052,   7.34292780e+223,   4.71235856e+257]])

3.3.7 ones_like  zero_like   empy_like函式

>>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
>>> a.shape
(3, 2, 2)
>>> b=np.ones_like(a)
>>> b
array([[[1, 1],
        [1, 1]],

       [[1, 1],
        [1, 1]],

       [[1, 1],
        [1, 1]]])
>>> b=np.zeros_like(a);b
array([[[0, 0],
        [0, 0]],

       [[0, 0],
        [0, 0]],

       [[0, 0],
        [0, 0]]])
>>> a=np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
>>> b=np.empty_like(a);b
array([[[39125057, 40012256],
        [81313824, 81313856]],

       [[       0,        0],
        [       0,        0]],

       [[       0,        0],
        [       0,        0]]])
#注意,shape和dtype均複製

 3.3.8  .T函式

  .T 作用於矩陣,用於求矩陣的轉置

>>myMat=np.mat([[1,2,3],[4,5,6]])
>>print(myMat)
>>matrix([[1.,2.,3.]
          [4.,5.,6.]])


>>print(myMat.T)
>>matrix([[1,4],
          [2,5],
          [3,6]])

  

3.3.9  tolist()函式

  tolost()函式用於把一個矩陣轉化為list列表

>>x=np.mat([[1,2,3],[4,5,6]])
>>print(x)
>>matrix([[1,2,3],[4,,5,6]])
>>type(x)
>>matrix
 
 
>>x.tolist()
>>[[1,2,3],[4,5,6]]

  

3.3.10  .I

  .I用於求矩陣的逆矩陣,逆矩陣在計算中是經常要用到的,例如一個矩陣A,求A的逆矩陣B,即存在矩陣B是AB=I(I是單位)

In [3]: a=mat([[1,2,3],[4,5,6]])
 
In [4]: a
Out[4]:
matrix([[1, 2, 3],
        [4, 5, 6]])
 
 
In [5]: a.I
Out[5]:
matrix([[-0.94444444,  0.44444444],
        [-0.11111111,  0.11111111],
        [ 0.72222222, -0.22222222]])
In [6]: s=a.I
 
In [8]: a*s
Out[8]:
matrix([[  1.00000000e+00,   3.33066907e-16],
        [  0.00000000e+00,   1.00000000e+00]])

  

3.3.11  .power(x1,x2)

  陣列的元素分別求n次方,x2可以是數字,也可以是陣列,但是x1和x2的列數要相同。

>>> x1 = range(6)
>>> x1
[0, 1, 2, 3, 4, 5]
>>> np.power(x1, 3)
array([  0,   1,   8,  27,  64, 125])

  

>>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
>>> np.power(x1, x2)
array([  0.,   1.,   8.,  27.,  16.,   5.])

  

>>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
>>> x2
array([[1, 2, 3, 3, 2, 1],
       [1, 2, 3, 3, 2, 1]])
>>> np.power(x1, x2)
array([[ 0,  1,  8, 27, 16,  5],
       [ 0,  1,  8, 27, 16,  5]])

  

3.3.12  reshape() 函式

  一般用法:numpy.arrange(n).reshape(a,b)

  意思:依次生成n個自然數,並且以a行b列的陣列形式顯示。

In [1]: 
np.arange(16).reshape(2,8) #生成16個自然數,以2行8列的形式顯示
Out[1]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15]])

  特殊用法:mat(or array).reshape(c,-1)

  必須是矩陣格式或者陣列格式,才能使用.reshape(c,-1)函式,表示將此矩陣或者陣列重組,以c行d 列的形式表示(-1的作用就在此,自動計算d:d=陣列或者矩陣裡面所有的元素個數(c,d必須為整數,不然會報錯))

In [2]: arr=np.arange(16).reshape(2,8)
out[2]:
 
In [3]: arr
out[3]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15]])
 
In [4]: arr.reshape(4,-1) #將arr變成4行的格式,列數自動計算的(c=4, d=16/4=4)
out[4]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
 
In [5]: arr.reshape(8,-1) #將arr變成8行的格式,列數自動計算的(c=8, d=16/8=2)
out[5]:
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15]])
 
In [6]: arr.reshape(10,-1) #將arr變成10行的格式,列數自動計算的(c=10, d=16/10=1.6 != Int)
out[6]:
ValueError: cannot reshape array of size 16 into shape (10,newaxis)

 

3.3.13 np.unique()的用法

  該函式是去除陣列中的重複數字,並進行排序之後輸出

a = [2,3,4,1,21,32,32,32,2,1]
b = [1,2,3,1,2,3]
c = [[1,2,3],[1,2,3],[2,3,4]]
resa = np.unique(a)
resb = np.unique(b)
resc = np.unique(c)
print('unique result a is :',resa)
print('unique result a is :',resb)
print('unique result a is :',resc)
'''
unique result a is : [ 1  2  3  4 21 32]
unique result a is : [1 2 3]
unique result a is : [1 2 3 4]
'''

  

3.3.14  np.argsort()的用法

  argsort()函式返回的是陣列值從小到達的索引值

    One dimensional array:一維陣列
    
    >>> x = np.array([3, 1, 2])
    >>> np.argsort(x)
    array([1, 2, 0])
    
    Two-dimensional array:二維陣列
    
    >>> x = np.array([[0, 3], [2, 2]])
    >>> x
    array([[0, 3],
           [2, 2]])
    
    >>> np.argsort(x, axis=0) #按列排序
    array([[0, 1],
           [1, 0]])
    
    >>> np.argsort(x, axis=1) #按行排序
    array([[0, 1],
           [0, 1]])

  舉個例子:

>>> x = np.array([3, 1, 2])
>>> np.argsort(x) #按升序排列
array([1, 2, 0])
>>> np.argsort(-x) #按降序排列
array([0, 2, 1])

>>> x[np.argsort(x)] #通過索引值排序後的陣列
array([1, 2, 3])
>>> x[np.argsort(-x)]
array([3, 2, 1])

另一種方式實現按降序排序:

>>> a = x[np.argsort(x)]
>>> a
array([1, 2, 3])
>>> a[::-1]
array([3, 2, 1])   

  

3.3.15 np.flatnonzero()

  該函式輸入一個矩陣,返回扁平化後矩陣中非零元素的位置(index)

  下面給出一個用法,輸入一個矩陣,返回了其中非零元素的位置:

>>> x = np.arange(-2, 3)
>>> x
array([-2, -1,  0,  1,  2])
>>> np.flatnonzero(x)
array([0, 1, 3, 4])
import numpy as np
d = np.array([1,2,3,4,4,3,5,3,6])
haa = np.flatnonzero(d == 3)
print (haa)

[2 5 7]

  對向量元素的判斷 d == 3,返回了一個和向量等長的由0/1組成的矩陣,然後再呼叫函式,返回的位置,就是對應要找的元素的位置。

# Visualize some examples from the dataset.
# We show a few examples of training images from each class.
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] #類別列表
num_classes = len(classes) #類別數目
samples_per_class = 7 # 每個類別取樣個數
for y, cls in enumerate(classes): # 對列表的元素位置和元素進行迴圈,y表示元素位置(0,num_class),cls元素本身'plane'等
    idxs = np.flatnonzero(y_train == y) #找出標籤中y類的位置
    idxs = np.random.choice(idxs, samples_per_class, replace=False) #從中選出我們所需的7個樣本
    for i, idx in enumerate(idxs): #對所選的樣本的位置和樣本所對應的圖片在訓練集中的位置進行迴圈
        plt_idx = i * num_classes + y + 1 # 在子圖中所佔位置的計算
        plt.subplot(samples_per_class, num_classes, plt_idx) # 說明要畫的子圖的編號
        plt.imshow(X_train[idx].astype('uint8')) # 畫圖
        plt.axis('off')
        if i == 0:
            plt.title(cls) # 寫上標題,也就是類別名
plt.show() # 顯示

  

3.3.16  np.nonzero()

  nonzero函式是numpy中用於得到陣列array中非零元素的目錄(位置)的函式。

  返回值為元組,兩個值分別為兩個維度,包含了相應維度上非零元素的目錄值。

  只有a中非零元素才會有索引值,那些零值元素沒有索引值

  當使用布林陣列直接作為下標物件或者元祖下標物件中有布林陣列時,都相當於用nonzero()講布林陣列轉換成一組整數陣列,然後使用整數陣列進行下標運算。

  nonzeros(a)返回陣列a中值不為零的元素的下標,它的返回值是一個長度為a.ndim(陣列a的軸數)的元組,元組的每個元素都是一個整數陣列,其值為非零元素的下標在對應軸上的值。例如對於一維布林陣列b1,nonzero(b1)所得到的是一個長度為1的元組,它表示b1[0]和b1[2]的值不為0(False)。

b = np.array([True,False,True,False])
b
array([ True, False,  True, False])
np.nonzero(b)
(array([0, 2], dtype=int64),)

  對於一個二維陣列c,nonzeero(c)所得到的是一個長度為2的元祖,它的第0個元素是陣列a中值不為0的元素的第0軸的下標,第一個元素則為第1軸的下標,因此從下面的結果可知b2[0,0]、b[0,2]和b2[1,0]的值不為0:

c = np.array([[True, False, True], [True, False, False]])
c
array([[ True, False,  True],
       [ True, False, False]])
np.nonzero(c)
(array([0, 0, 1], dtype=int64), array([0, 2, 0], dtype=int64))

 

3.3.17  np.column_stack(tup)

  np.column_stack(tup)相當於np.concatenate((a1, a2, …), axis=1),對豎軸的陣列進行橫向的操作。

 官方解釋(如果傳遞的是一個一維陣列,則會先將一維陣列轉化為2維陣列):

    Stack 1-D arrays as columns into a 2-D array.

    Take a sequence of 1-D arrays and stack them as columns
    to make a single 2-D array. 2-D arrays are stacked as-is,
    just like with `hstack`.  1-D arrays are turned into 2-D columns
    first.

    Parameters
    ----------
    tup : sequence of 1-D or 2-D arrays.
        Arrays to stack. All of them must have the same first dimension.

    Returns
    -------
    stacked : 2-D array
        The array formed by stacking the given arrays.

    See Also
    --------
    stack, hstack, vstack, concatenate

  舉例說明:

  如果開始傳入的是一維陣列,首先將一維陣列轉化為二維陣列

import numpy as np

a = np.array((1, 2, 3))
b = np.array((2, 3, 4))
c = np.column_stack((a, b))

print(a)
print(b)
print(c)
# 結果:
[1 2 3]
[2 3 4]
[[1 2]
 [2 3]
 [3 4]]

  如果一開始傳入的是多維陣列,則直接進行拼接操作

import numpy as np

a = np.array(((1, 2, 3), (4, 3, 2)))
b = np.array(((2,3,4),(2,12,2)))
c = np.column_stack((a,b))
print(a)
print(b)
print(c)
# 結果:
[[1 2 3]
 [4 3 2]]
[[ 2  3  4]
 [ 2 12  2]]
[[ 1  2  3  2  3  4]
 [ 4  3  2  2 12  2]]

  

四,Numpy資料型別

  NumPy 支援比 Python 更多種類的數值型別。 下表顯示了 NumPy 中定義的不同標量資料型別。

序號資料型別及描述
1. bool_儲存為一個位元組的布林值(真或假)
2. int_預設整數,相當於 C 的long,通常為int32或int64
3. intc相當於 C 的int,通常為int32或int64
4. intp用於索引的整數,相當於 C 的size_t,通常為int32或int64
5. int8位元組(-128 ~ 127)
6. int1616 位整數(-32768 ~ 32767)
7. int3232 位整數(-2147483648 ~ 2147483647)
8. int6464 位整數(-9223372036854775808 ~ 9223372036854775807)
9. uint88 位無符號整數(0 ~ 255)
10. uint1616 位無符號整數(0 ~ 65535)
11. uint3232 位無符號整數(0 ~ 4294967295)
12. uint6464 位無符號整數(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(資料型別)物件的例項,每個物件具有唯一的特徵。 這些型別可以是np.bool_,np.float32等。

4.1 資料型別物件(dtype)

資料型別物件描述了對應於陣列的固定記憶體塊的解釋,取決於以下方面:

  • 資料型別(整數、浮點或者 Python 物件)

  • 資料大小

  • 位元組序(小端或大端)

  • 在結構化型別的情況下,欄位的名稱,每個欄位的資料型別,和每個欄位佔用的記憶體塊部分。

  • 如果資料型別是子序列,它的形狀和資料型別。

  位元組順序取決於資料型別的字首<或>。<意味著編碼是小端(最小有效位元組儲存在最小地址中)。>意味著編碼是大端(最大有效位元組儲存在最小地址中)。

dtype語法構造:

numpy.dtype(object, align, copy)

 引數為:

Object:被轉換為資料型別的物件。 

Align:如果為true,則向欄位新增間隔,使其類似 C 的結構體。 

Copy: 生成dtype物件的新副本,如果為flase,結果是內建資料型別物件的引用。

 示例:

# 使用陣列標量型別
import numpy as np
dt = np.dtype(np.int32)
print(dt)
# int32

# int8,int16,int32,int64 可替換為等價的字串 'i1','i2','i4',以及其他。
dt = np.dtype('i4')
print(dt)
# int32

# 使用端記號
dt = np.dtype('>i4')
print(dt)
# >i4

# 首先建立結構化資料型別。
dt = np.dtype([('age',np.int8)])
print(dt)
# [('age', 'i1')]

# 現在將其應用於 ndarray 物件
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a)
# [(10,) (20,) (30,)]

# 檔名稱可用於訪問 age 列的內容
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a['age'])
# [10 20 30]

 

五,Numpy 切片和索引

  ndarray物件的內容可以通過索引或切片來訪問和修改,就像python的內建容器物件一樣。

  nadarray 物件中的元素遵循基於零的索引,有三種可用的索引方法型別:欄位訪問,基礎切片和高階索引。

  基本切片是Python中基本切片概念到n維的擴充套件,通過start,stop和step引數提供給內建函式的slice函式來構造一個Python slice物件,此slice物件被傳遞給陣列來提取陣列的一部分。

練習:

import numpy as np

a = np.arange(10)
print(a)
# [0 1 2 3 4 5 6 7 8 9]
s = slice(2,7,2)
print(s)
# slice(2, 7, 2)
print(a[s])
# [2 4 6]

b = a[2:7:2]
print(b)
# [2 4 6]

# 對單個元素進行切片
b = a[5]
print(b)
# 5

# 對始於索引的元素進行切片
print(a[2:])
# [2 3 4 5 6 7 8 9]

# 對索引之間的元素進行切片
print(a[2:5])
# [2 3 4]


# 二維陣列
# 最開始的陣列
import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print('我們的陣列是:')
print(a)
print ('\n')
# 這會返回第二列元素的陣列:
print ('第二列的元素是:')
print(a[...,1])
print('\n')
# 現在我們從第二行切片所有元素:
print ('第二行的元素是:')
print(a[1,...])
print( '\n')
# 現在我們從第二列向後切片所有元素:
print ('第二列及其剩餘元素是:')
print(a[...,1:])
'''
我們的陣列是:
[[1 2 3]
 [3 4 5]
 [4 5 6]]


第二列的元素是:
[2 4 5]


第二行的元素是:
[3 4 5]


第二列及其剩餘元素是:
[[2 3]
 [4 5]
 [5 6]]'''

 

六,numpy中的ndarray與array的區別

  答:Well, np.array is just a convenience function to create an ndarray, it is not a class itself.
(嗯,np.array只是一個便捷的函式,用來建立一個ndarray,它本身不是一個類)

  You can also create an array using np.ndarray, but it is not the recommended way. From the docstring of np.ndarray:
(你也能夠用np.ndarray來建立,但這不是推薦的方式。來自np.ndarray的文件:)

 numpy函式:shape用法