numpy 是使用python進行資料分析不可或缺的第三方庫,非常多的科學計算工具都是基於 numpy 進行開發的。
ndarray對象是用於存放同類型元素的多維陣列,是numpy中的基本對象之一,另一個是func對象。本文主要內容是:1 、簡單介紹ndarray對象;2、ndarray對象的常用屬性;3、如何建立ndarray對象;4、ndarray元素訪問。
它的維度以及個維度上的元素個數由shape決定。 1 numpy.ndarray()
標題中的函數就是numpy的建構函式,我們可以使用這個函數建立一個ndarray對象。建構函式有如下幾個選擇性參數:
| 參數 |
類型 |
作用 |
| shape |
int型tuple |
多維陣列的形狀 |
| dtype |
data-type |
數組中元素的類型 |
| buffer |
|
用於初始化數組的buffer |
| offset |
int |
buffer中用於初始化數組的首個資料的位移 |
| strides |
int型tuple |
每個軸的下標增加1時,資料指標在記憶體中增加的位元組數 |
| order |
‘C’ 或者 ‘F’ |
‘C’:行優先;’F’:列優先 |
執行個體:
>>> np.ndarray(shape=(2,3), dtype=int, buffer=np.array([1,2,3,4,5,6,7]), offset=0, order="C") array([[1, 2, 3], [4, 5, 6]])>>> np.ndarray(shape=(2,3), dtype=int, buffer=np.array([1,2,3,4,5,6,7]), offset=0, order="F")array([[1, 3, 5], [2, 4, 6]])>>> np.ndarray(shape=(2,3), dtype=int, buffer=np.array([1,2,3,4,5,6,7]), offset=8, order="C") array([[2, 3, 4], [5, 6, 7]])
2 ndarray對象的常用屬性
接下來介紹ndarray對象最常用的屬性
| 屬性 |
含義 |
| T |
轉置,與self.transpose( )相同,如果維度小於2返回self |
| size |
數組中元素個數 |
| itemsize |
數組中單個元素的位元組長度 |
| dtype |
數組元素的資料類型對象 |
| ndim |
數組的維度 |
| shape |
數組的形狀 |
| data |
指向存放數組資料的python buffer對象 |
| flat |
返回數組的一維迭代器 |
| imag |
返回數組的虛部 |
| real |
返回數組的實部 |
| nbytes |
數組中所有元素的位元組長度 |
執行個體:
>>> a = np.array(range(15)).reshape(3,5)>>> aarray([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])>>> a.Tarray([[ 0, 5, 10], [ 1, 6, 11], [ 2, 7, 12], [ 3, 8, 13], [ 4, 9, 14]])>>> a.size15>>> a.itemsize8>>> a.ndim2>>> a.shape(3, 5)>>> a.dtypedtype('int64')
3 建立ndarray
3.1 array
使用array函數,從常規的python列表或者元組中建立數組,元素的類型由原序列中的元素類型確定。
numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0)
執行個體:
>>> np.array([1, 2, 3])array([1, 2, 3])>>> np.array([[1, 2],[3, 4]])array([[1, 2], [3, 4]])>>> c = array( [ [1,2], [3,4] ], dtype=complex )>>> carray([[1.+0.j, 2.+0.j], [3.+0.j, 4.+0.j]])>>> a = np.array([1, 2, 3], ndmin=2)>>> aarray([[1, 2, 3]])>>> a.shape(1, 3)>>> np.array(np.mat('1 2; 3 4'))array([[1, 2], [3, 4]])>>> np.array(np.mat('1 2; 3 4'), subok=True)matrix([[1, 2], [3, 4]])
subok為True,並且object是ndarray子類時(比如矩陣類型),返回的數組保留子類類型 3.2 ones與zeros系列函數
某些時候,我們在建立數組之前已經確定了數組的維度以及各維度長度。這時我們就可以使用numpy內建的一些函數來建立ndarray。
例如:函數ones建立一個全1的數組、函數zeros建立一個全0的數組、函數empty建立一個內容隨機的數組,在預設情況下,用這些函數建立的數組的類型都是float64,若需要指定資料類型,只需要閑置dtype參數即可:
>>> a = np.ones(shape = (2, 3)) #可以通過元組指定數組形狀>>> aarray([[ 1., 1., 1.], [ 1., 1., 1.]])>>> a.dtypedtype('float64')>>> b = np.zeros(shape = [3, 2], dtype=np.int64) #也可以通過列表來指定數組形狀,同時這裡指定了數群組類型>>> barray([[0, 0], [0, 0], [0, 0]])>>> b.dtypedtype('int64')>>> c = np.empty((4,2))>>> carray([[ 0.00000000e+000, 0.00000000e+000], [ 6.92806325e-310, 6.92806326e-310], [ 6.92806326e-310, 6.92806326e-310], [ 0.00000000e+000, 0.00000000e+000]])
上述三個函數還有三個從已知的數組中,建立shape相同的多維陣列:ones_like、zeros_like、empty_like,用法如下:
>>> a = [[1,2,3], [3,4,5]]>>> b = np.zeros_like(a)>>> barray([[0, 0, 0], [0, 0, 0]])#其他兩個函數用法類似
除了上述幾個用於建立數組的函數,還有如下幾個特殊的函數:
| 函數名 |
用途 |
| eye |
產生對角線全1,其餘位置全是0的二維數組 |
| identity |
產生單位矩陣 |
| full |
產生由固定值填充的數組 |
| full_like |
產生由固定值填充的、形狀與給定數組相同的數組 |
特別地,eye函數的全1的對角線位置有參數k確定
用法如下:
>>> np.eye(3, k = 0) #k=0時,全1對角線為主對角線array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])>>> np.eye(3, k = 1) #k>0時,全1對角線向上移動相應的位置array([[ 0., 1., 0.], [ 0., 0., 1.], [ 0., 0., 0.]])>>> np.eye(3, k = -1) #k<0時,全1對角線向下移動相應的位置array([[ 0., 0., 0.], [ 1., 0., 0.], [ 0., 1., 0.]])>>> np.identity(4)array([[ 1., 0., 0., 0.], [ 0., 1., 0., 0.], [ 0., 0., 1., 0.], [ 0., 0., 0., 1.]])>>> np.full(shape = (2,2), fill_value = 2)array([[ 2., 2.], [ 2., 2.]])>>> np.full_like([[1,2,3],[3,4,5]], 3)array([[3, 3, 3], [3, 3, 3]])
3.3 arange、linspace與logspace arange函數類似python中的range函數,通過指定初始值、終值以及步長(預設步長為1)來建立數組 linspace函數通過指定初始值、終值以及元素個數來建立
一維數組 logspace函數與linspace類似,只不過它建立的是一個等比數列,同樣的也是一個一維數組
執行個體:
>>> np.arange(0,10,2) array([0, 2, 4, 6, 8])>>> np.arange(0,10)array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.linspace(0,10, 20)array([ 0. , 0.52631579, 1.05263158, 1.57894737, 2.10526316, 2.63157895, 3.15789474, 3.68421053, 4.21052632, 4.73684211, 5.26315789, 5.78947368, 6.31578947, 6.84210526, 7.36842105, 7.89473684, 8.42105263, 8.94736842, 9.47368421, 10. ])>>> np.logspace(0, 10, 10)array([ 1.00000000e+00, 1.29154967e+01, 1.66810054e+02, 2.15443469e+03, 2.78255940e+04, 3.59381366e+05, 4.64158883e+06, 5.99484250e+07, 7.74263683e+08, 1.00000000e+10])
3.4 fromstring與fromfunction fromstring函數從字串中讀取資料並建立數組 fromfunction函數由第一個參數作為計算每個數組元素的函數(函數對象或者lambda運算式均可),第二個參數為數組的形狀
執行個體:
>>> s1 = "1,2,3,4,5">>> np.fromstring(s1, dtype=np.int64, sep=",")array([1, 2, 3, 4, 5])>>> s2 = "1.01 2.23 3.53 4.76">>> np.fromstring(s2, dtype=np.float64, sep=" ")array([ 1.01, 2.23, 3.53, 4.76])>>> def func(i, j):... return (i+1)*(j+1)... >>> np.fromfunction(func, (9,9))array([[ 1., 2., 3., 4., 5., 6., 7., 8., 9.], [ 2., 4., 6., 8., 10., 12., 14., 16., 18.], [ 3., 6., 9., 12., 15., 18., 21., 24., 27.], [ 4., 8., 12., 16., 20., 24., 28., 32., 36.], [ 5., 10., 15., 20., 25., 30., 35., 40., 45.], [ 6., 12., 18., 24., 30., 36., 42., 48., 54.], [ 7., 14., 21., 28., 35., 42., 49., 56., 63.], [ 8., 16., 24., 32., 40., 48., 56., 64., 72.], [ 9., 18., 27., 36., 45., 54., 63., 72., 81.]])>>> np.fromfunction(lambda i,j: i+j, (3,3), dtype = int)array([[0, 1, 2], [1, 2, 3], [2, 3, 4]])
除了上面兩個函數還有其他幾個類似的從外部擷取資料並建立ndarray,比如:frombuffer、fromfile、fromiter,還沒用過,等用到了在詳細記錄 4 ndarray建立特殊的二維數組
ndarray提供了一些建立二維數組的特殊函數。numpy中matrix是對二維數組ndarray進行了封裝之後的子類。這裡介紹的關於二維數組的建立,返回的依舊是一個ndarray對象,而不是matrix子類。關於matrix的建立和操作,待後續筆記詳細描述。為了表述方便,下面依舊使用矩陣這一次來表示建立的二維數組。
1. diag函數返回一個矩陣的對角線元素、或者建立一個對角陣,對角線由參數k控制
2. diagflat函數以輸入作為對角線元素,建立一個矩陣,對角線由參數k控制
3. tri函數產生一個矩陣,在某對角線以下元素全為1,其餘全為0,對角線由參數k控制
4. tril函數輸入一個矩陣,返回該矩陣的下三角矩陣,下三角的邊界對角線由參數k控制
5. triu函數與tril類似,返回的是矩陣的上三角矩陣
6. vander函數輸入一個一維數組,返回一個範德蒙德矩陣
#diag用法>>> x = np.arange(9).reshape((3,3))>>> xarray([[0, 1, 2], [3, 4, 5], [6, 7, 8]])>>> np.diag(x)array([0, 4, 8])>>> np.diag(x, k=1)array([1, 5])>>> np.diag(x, k=-1)array([3, 7])>>> np.diag(np.diag(x))array([[0, 0, 0], [0, 4, 0], [0, 0, 8]])>>> np.diag(np.diag(x), k=1)array([[0, 0, 0, 0], [0, 0, 4, 0], [0, 0, 0, 8], [0, 0, 0, 0]])#diagflat用法>>> np.diagflat([[1,2],[3,4]])array([[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]])>>> np.diagflat([1,2,3], k=-1)array([[0, 0, 0, 0], [1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0]])#tri>>> np.tri(3,4, k=1, dtype=int) array([[1, 1, 0, 0], [1, 1, 1, 0], [1, 1, 1, 1]])>>> np.tri(3,4)array([[ 1., 0., 0., 0.], [ 1., 1., 0., 0.], [ 1., 1., 1., 0.]])#tril與triu>>> x = np.arange(12).reshape((3,4))>>> xarray([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])>>> np.tril(x, k=1) array([[ 0, 1, 0, 0], [ 4, 5, 6, 0], [ 8, 9, 10, 11]])>>> np.triu(x, k=1) array([[ 0, 1, 2, 3], [ 0, 0, 6, 7], [ 0, 0, 0, 11]])#vander>>> np.vander([2,3,4,5])array([[ 8, 4, 2, 1], [ 27, 9, 3, 1], [ 64, 16, 4, 1], [125, 25, 5, 1]])>>> np.vander([2,3,4,5], N=3)array([[ 4, 2, 1], [ 9, 3, 1], [16, 4, 1], [25, 5, 1]])
5 ndarray元素訪問
5.1 一維數組
對於一維的ndarray可以使用python訪問內建list的方式進行訪問:整數索引、切片、迭代等方式
關於ndarray切片
與內建list切片類似,形式:
array[beg:end:slice]
beg: 開始索引
end: 結束索引(不包含這個元素)
step: 間隔
需要注意的是:
1. beg可以為空白,表示從索引0開始;
2. end也可以為空白,表示達到索引結束(包含最後一個元素);
3. step為空白,表示間隔為1;
4. 負值索引:倒數第一個元素的索引為-1,向前以此減1
5. 負值step:從後往前擷取元素
>>> x = np.arange(16)*4>>> xarray([ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60])>>> x[11]44>>> x[4:9]array([16, 20, 24, 28, 32])>>> x[:10:3]array([ 0, 12, 24, 36])>>> x[0:13:2]array([ 0, 8, 16, 24, 32, 40, 48])>>> x[::-1] #逆置數組array([60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4, 0])>>> print [val for val in x] #迭代元素[0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60]
特別注意的是,ndarray中的切片返回的數組中的元素是原數組元素的索引,對返回數組元素進行修改會影響原數組的值
>>> x[:-1]array([ 0, 5, 10, 15, 20, 25, 30, 35, 40])>>> y = x[::-1]>>> yarray([45, 40, 35, 30, 25, 20, 15, 10, 5, 0])>>> y[0] = 100 #修改y的首個元素的值>>> yarray([100, 40, 35, 30, 25, 20, 15, 10, 5, 0])>>> x #x[-1]也被修改(本質上是一個元素)array([ 0, 5, 10, 15, 20, 25, 30, 35, 40, 100])
除了上述與list相似的訪問元素的方式,ndarray有一種通過列表來指定要從ndarray中擷取元素的索引,例如:
>>> x = np.arange(10)*5>>> xarray([ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45])>>> x[[0, 2, 4, 5, 9]] #指定擷取索引為0、2、4、5、9的元素array([ 0, 10, 20, 25, 45])
5.2 多維陣列
多維ndarray中,每一維都叫一個軸axis。在ndarray中軸axis是非常重要的,有很多對於ndarray對象的運算都是基於axis進行,比如sum、mean等都會有一個axis參數(針對對這個軸axis進行某些運算操作),後續將會詳細介紹。
對於多維陣列,因為每一個軸都有一個索引,所以這些索引由逗號進行分割,例如:
>>> x = np.arange(0, 100, 5).reshape(4, 5)>>> xarray([[ 0, 5, 10, 15, 20], [25, 30, 35, 40, 45], [50, 55, 60, 65, 70], [75, 80, 85, 90, 95]])>>> x[1,2] #第1行,第2列35>>> x[1:4, 3] #第1行到第3行中所有第