首先說一下這篇文章不是NumPy的教程,而是對學習的記錄,旨在在以后需要用的時候能夠知道What is NumPy。鎮上官方NumPy參考手冊,這才是系統學習NumPy的真正去處。
約定:
import numpy as np
簡介:
NumPy(Numerical Python)是高性能科學計算和數據分析的基礎包。NumPy的主要對象是同構數據多維容器(homogeneous multidimensional array)——ndarray,也就是說每一個ndarray都是一個相同類型元素組成的表格(二維)。在NumPy中維度(dimensions)叫做軸(axes),軸的個數叫做秩(rank)。軸這個概念必須牢記,否則放棄吧。首先軸是從0開始計的,0代表最高維,次高維是1,以此類推。
還有兩個概念需要認識:
- 面向數組——NumPy本身并沒有提供多么高級的數據分析功能,理解NumPy數組以及面向數組的計算將有助于你更加高效地使用諸如pandas之類的工具。
- 矢量化(vectorization)——用數組表達式代替循環的做法。一般來說,矢量化數組運算要比等價的純Python方式快上一兩個數量級(甚至更多),尤其是各種數值計算。
ndarray屬性
- ndarray.ndim——ndarray的秩。
- ndarray.shape——書面意思ndarray的形狀。官方解釋是各維度的大小所組成的tuple元組。
- ndarray.size——數組元素的總個數,等于shape屬性中元組元素的乘積。
- ndarray.dtype——是一個特殊的對象,它含有ndarray將一塊內存解釋為特定數據類型所需的信息。ndarray內部由一個指向數組的指針,一個數據類型,一個表示形狀的元組和一個跨度元組(跨越某一維度所需字節數)。由于NumPy關注的是數值計算,所以沒有特別指定,dtype基本都是float64(浮點數),果然是基本,
np.arange(10)
產生的數組類型是int32,嗯,推斷的還算合理吧。 - ndarray.itemsize——書面意思項大小,就是數組中每一個元素所占字節大小。
- ndarray.data——官方說不需要使用,so 沒細研究。
創建ndarray
函數 | 說明 |
---|---|
np.array(data,dtype=None, order=None) | 將數據data(列表、元組、數組或其他序列類型)轉換為ndarray。要么推斷出dtype,要么顯示指定dtype。默認直接復制數據。order默認是A(可能是C可能是F還可能是其它) |
np.asarray(data, dtype=None, order=None) | 將輸入數據轉換為ndarray,data同上還可以是ndarray,如果是ndarray就不進行復制。dtype同上,order是重塑中行優先C還是列優先F,默認C語言風格。 |
np.arange(10,30,5,dtype=None) | 開始,結束,步長和內置的range相同 |
np.ones( (2,3,4), dtype=None) 、np.ones_like(a) | 根據指定的形狀和dtype創建一個全1的數組。ones_like以另一個數組為參數,創建形狀和dtype相同的全1數組。 |
np.zeros() 、np.zeros_like() | 全0數組,類似ones和ones_like。 |
np.empty() 、np.empty_like() | 創建數組,只分配內存空間但不填充任何值,所以返回的是垃圾值。類似ones和ones_like。 |
np.eye(N, M=None, k=0, dtype=<type 'float'>) 、np.identity(n, dtype=None) | eye創建的是N*M的數組,默認M=N,k取整數,正數對角線向上移k,負數對角線向下移k。identity創建一個N*N單位矩陣(\對角線為1,其余全0)的數組 |
操作
算術運算
大小相等的數組之間的任何算術運算都會將運算應用到元素級。
數組與標量的算術運算也將會將那個標量值傳播到各個元素。
當dtype不一致時,采用上溯造型(upcasting)
邏輯運算
<、>、<=、>=、==、!=和&(和)、|(或)、-(非),這些運算符和算術運算符的使用一致,只不過將產生一個新的布爾型數組。
集合運算
NumPy提供了一些針對一維ndarray的基本集合運算。
函數 | 說明 |
---|---|
np.unique(x, return_counts=False) | 計算x中的唯一元素,并返回有序數組, return_counts=True時一并返回對應元素的數量數組。 |
np.intersect1d(x,y) | (交)計算x,y中的公共元素,并返回有序數組 |
np.union1d(x,y) | (并)計算x,y的并集,并返回有序數組 |
np.in1d(x,y) | (包含)得到一個表示x的元素是否包含于y的布爾型數組 |
np.setdiff1d(x,y) | (差)集合的差,即元素在x中且不在y中 |
np.setxor1d(x,y) | (異或)集合的對稱差,即存在于一個數組中但不同時存在于兩個數組中的元素。 |
索引
索引這一節一句半句說不清,另起一篇來寫。
形狀操縱
reshape(x,y,...)返回修改的新數組,resize((x,y,...))返回修改后的自身。
轉置:
轉置(transpose)是重塑的一種特殊形式它返回的是源數據的視圖。數組不僅有transpose方法,還有一個特殊的T屬性。簡單的轉置可以使用.T
,他其實就是進行軸對換而已。ndarray還有一個swapaxes方法,他需要接受一對軸編號eg:swapaxes(0,1)。對于高維數組transpose需要一個軸編號組成的元組才能對這些軸進行轉置。
這里對transpose解釋一下
In [4]: arr = np.arange(16).reshape((2,2,4))
In [5]: arr
Out[5]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [6]: arr.transpose((1,0,2))
Out[6]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
簡而言之就是將原來的0,1,2軸變成現在的1,0,2,轉換后的0軸是原來的1軸,轉換后的1軸是原來的0軸,2軸未變。
換種解釋:比如說8元素的索引是[1,0,0],0,1軸變換后是[0,1,0]。
組合不同的數組(堆stack):
hstack
, vstack
, column_stack
, concatenate
, c_
, r_
其他
用于數組的文件輸入輸出
NumPy能夠讀寫磁盤上的文本數據或二進制數據。
np.save和np.load是讀寫磁盤數組數據的兩個主要函數。默認情況下,數據是以未壓縮的原始二進制格式保存在擴展名為.npy的文件中的。如果文件路徑末尾沒有擴展名.npy,則該擴展名會被自動加上。通過np.savez可以將多個數組保存到一個壓縮文件中,將數組以關鍵字參數的形式傳入即可np.savez('array_archive.npz',a=arr1, b=arr2)
,加載.npz文件時,你會得到一個類似字典的對象,該對象會對各個數組進行延遲加載。
NumPy提供了從文件中加載文本的函數np.loadtxt(),還有更為專門化的np.genfromtxt()將數據加載到普通的NumPy數組中,只不過他面向的是結構化數組和缺失數據處理。這些函數都許多選項可供使用:指定各種分隔符、針對特定列的轉換器函數、需要跳過的行數等。完整版的np.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
,注解默認‘#’,分隔符默認whitespace空白,converters = dict{columu : function}。np.savetxt()執行的是相反的操作。
復制和視圖
簡單的賦值不拷貝數組對象或者他們的數據;視圖就是同一數據的引用,改視圖,就是改數據;切片返回的是視圖。顯示復制用copy()函數。其實考慮一下NumPy工具出現的目的也能明白,能夠高效、快速處理大量數據,老是復制多費勁,還占內存。
如有理解不正確之處或者解釋不通的地方,歡迎指正,共同進步,有時候個人的理解并不能解釋忽略的、更高層面情況。