前言
numpy是一個很基礎很底層的子產品,其重要性不言而喻,可以說對于新手來說是最基礎的入門必須要學習的其中之一。在很多資料分析,深度學習,機器學習亦或是人工智能領域的子產品中,很多的底層都會用到這個子產品,是必知必會的一個基礎子產品。
那麼numpy作為這麼基礎的一個子產品,它是幹什麼的,它的主要功能是處理什麼的,我可以直接告訴你,numpy主要用于數組的批量運算。
anaconda的安裝
anaconda是一個開源的python版本,其包含了大量用于科學計算的包以及依賴項,是以資料分析或者科學計算,我們通常都會使用anaconda這個python版本,因為其中就包括了諸如numpy、pandas等子產品,使用很友善。
anaconda的簡單使用介紹
打開anaconda,Windows下指令行直接搜素anaconda,就會出來一個anaconda navigator,點選運作,就會出現如下界面
home頁面會出現好多很好用的工具,包括自帶的IDE,諸如 vscode、Spyder、jupyter等
environments就是用于環境的管理,類似于虛拟環境,可以自己定制自己需要的環境
learning裡面都是很多的document文檔
小結:
1.使用anaconda時,包管理器有兩種,一種是conda <比如:conda install django>,另一種是pip,最好使用conda這個包管理器,因為在anaconda中繼續使用python原本的包管理器pip,下載下傳的包會預設下載下傳到base中,是以最好使用conda
2.IPython解釋器的不同,IPython的互動指令特别好看,更加友好,而且可以使用很多進階的指令,比如可以使用tab鍵進行補全後者檢視所有可用的方法,在這些方法後加?可以檢視目前方法的使用文檔,還有IPython的指令行跟linux的很多基礎指令是一樣的,當然如果要在IPython的指令行中使用Windows的一些指令,需要在指令前加!
3.jupyter notebook 的使用,為啥不用其他IDE比如pycharm,因為所有的資料科學計算都是嘗試性的工作,比如:做一個簡單的求和運算,我們的做法就是先将資料讀進來,然後運算,發現結果不行,再次進行其他運算就需要再次讀入資料,如果資料量很大,一般資料科學的資料都很大,就會導緻花費大量的時間進行讀資料的操作,很浪費時間,而jupyter在這方面做得很好,它裡面包含了很多單元格,每個單元格都是獨立的,我們完全可以其中一個單元格運來存放讀入的資料,然後在下面的單元格中使用,就會很友善。
接下來,回到我們今天本篇部落格的主題上來,numpy的使用
numpy的使用
誠如上面所說,numpy是一個高性能科學計算和資料分析的基礎包,它是pandas等其他各種工具的基礎。
numpy的主要功能:
1. ndarray,一個多元資料結構,高效且節省空間
2. 無需循環對整組資料進行快速運算的數學函數
3. 讀寫磁盤資料的工具以及用于操作記憶體映射檔案的工具
4. 線性代數、随機數生成和傅裡葉變換功能
5. 使用者內建C、C++等代碼的工具
安裝
pip/conda install numpy
備注:使用時,引入numpy時,大家約定成俗為 import numpy as np
使用
1.建立ndarray的方式:np.array()
np.array(li...) ---> ndarray 使用array方法,傳入任意的清單,都可以轉化為ndarray資料格式
ndarray是多元數組結構,與清單的差別:
1.數組對象内的元素類型必須相同
2.數組大小不可修改
ndarray格式的好處:
1.運作和執行效率快<更底層的優化處理,針對CPU做的批量處理的優化>,省記憶體<清單的存儲是存儲的對應資料的位址,而數組存儲的是資料本身>
2.可以快速簡單實作對大量的資料進行批量的運算 ,ndarray直接可以運算
備注: 使用jupyter時,輸入輸出結束時,可以使用快捷鍵 shift+enter 執行該單元格。上圖輸出為ndarray資料格式的輸出格式
3. 兩個相同長度為 m 的ndarray相乘,結果為m個值,兩個對應的索引相乘,執行了一層循環,差別于兩個相同長度的清單相乘,為兩層循環,結果為 m**2個值
4.ndarray的求和運算 直接使用 ndarray.sum(), 或者也可以使用sum(ndarray),個人還是推薦使用前一種,為啥,感覺這個方法是numpy自身提供的,感覺内部肯定做了處理,運作和性能更好。
5. ndarray.size 擷取ndarray中的元素個數,不管是幾維清單,都可以獲得所有的元素
6. ndarray.shape 以元組的形式傳回目前ndarray對象的形狀,即 是幾維的清單
7. ndarray.ndim 用于判斷目前ndarray對象的次元,幾維就傳回幾
8. ndarray.T 隻使用于高維清單(二維以上), 表示将數組轉置,即将數組轉90度,行變成列,列變成行
如圖: 二維的轉置
三維的轉置
9. ndarray.dtype 傳回目前ndarray的資料類型, 類型的轉換 ndarray.astype("類型名")
備注: numpy是頂層使用的python文法,而底層是基于c自己實作了很多資料類型
ndarray的所有的資料類型:
特别注意: 為了差別于python中 的bool、int、float等類型,numpy的bool為bool_ 會加一個_
補充:我們都知道,int32表示32位的整數,在計算機中,32位的整數是有範圍的,從 -2**31 ~ 2 **31-1,如果超過這個數就會造成記憶體的溢出
一般情況下不會出現這種現象,如果需要或者出現這種場景,如何解決呢?ndarray提供了一種資料類型轉化或者說是聲明的一種方式:ndarray.astype("int64") 注意:括号中為要轉換的字元串格式的資料類型
另外,我們在建立ndarray對象時,可以指定要建立的ndarray的類型 np.array([...], dtype="類型")
以上都是ndarray這個對象的使用方法,除了建立一個ndarray之外,numpy還有其他的一些方法
比如:
2、np.arange()
同python的range方法一樣,傳回一個數組,可以設定起點,終點,步長,比python中range這個方法更nb的是,他還支援小數級别的步長,預設情況下,arange的步長為1
補充:預設情況下np.arange生成的數組為一維的,那如何生成二維或者更多元的呢? np.arange提供了一個方法: np.arange(n).reshape(次元)
通過上圖,心細的小夥伴肯定會問,你這有問題啊,reshape(3,5) 跟 reshape(3,-1) 結果都是生成了一個3行5列的二維數組啊,是一樣的結果,其實這就是numpy底層實作的機制了,通過總數量,在已知n個次元上的n-1個數,numpy内部會預設計算出剩下的一位,是以才會如此。
3. np.linspace() 類似于arange方法,不同于arange的是,linspace的第三個參數不是步長,而是指定目前數組的元素個數
可以這麼了解:比如 np.linspace(1,8,10) 将1到8之間分成9(10-1)份,使得最後的數組中有十個數,而且每個數之間的內插補點是一樣的
4. np.zeros() np.ones() np.empty() 這三個是一組,表示建立一個指定形狀的數組,可以額外使用dtype參數指定要建立數組的資料類型
差別: zeros 表示建立一個值都為0的數組, ones 表示建立一個值都為 1 的數組, empty 表示建立一個數組,不指定值
備注: zeros和ones的内部是這樣的,程式向申請一塊多少大小的記憶體,然後再将這個記憶體中的值全換替換為0或1,而empty隻是申請一塊内部才能,而不會去指派,所有empty的執行效率會更好一些,如果我們隻是申請一個數組,同時能夠保證這個數組中的每個數都會有值,就可以直接使用empty。
5 np.eye() 和 np.identity() 建立指定形狀和dtype的機關矩陣
索引和切片
數組的索引
一維數組與清單的索引是一樣的,直接 : array[3]
對于多元數組,使用索引時,有兩種表示方式:
1. 直接按照該次元數組的順序取,比如: 二維數組取第3行第5列的數 :array[3][5]
2. 更推薦的寫法,多個次元之間使用逗号隔開 array[3,5]
數組的切片
一維的數組切片跟清單是一樣的
多元的清單,切片時,比如: 二維數組從第2行第3列切到第4行第8列 : array[2:4,3:8] 前面的表示先從第2行切到第4行,在取第3列到第8列
備注:
python中對清單進行切片,用一個新的變量指向他,我們修改這段切片的值,是不會修改原來清單中對應的值的,而數組不同,修改切片的值,就會修改原來數組的值。
比如:python的清單
li = [1,2,3,4,5,6,7,8]
a = li[3:5]
a[0] = 12
print(li) # 結果不變
數組對應的情形
數組的切片不同于清單的切片的原因:在python中,對清單切片等同于淺copy,淺拷貝第一層的位址是獨立的,因為python的清單的底層實作不同于數組的底層實作,數組中存的就是該值,是以,數組的大小是無法改變的,而python的清單大小是可以随便改變的,因為python的底層中清單中存的是一個位址,一個指向該值的位址,python的切片就會copy一份該段清單的位址,改變其中某一個值,隻是改變了copy出來的這段位址的一個指向的位址,而原清單中該值的指向位址是不變的,是以修改python的切片中的某一個值并不會改變原清單。而數組中存的就是該值,數組的切片隻是告訴計算機,我這個變量表示的是這一段,類似了資料庫中的視圖,修改視圖就會修改原來的。
那我如果想修改數組切片的值還不改變原數組值,那怎麼辦呢,很簡單,直接使用 copy方法 a = array[3:6].copy(),這樣在修改a的值,原數組是不會發生改變的,如圖,不信自己試試
接下來是numpy的重頭戲,最長用的操作
numpy的布爾型索引
可能很多人跟我一樣,剛開始看到這個名字還有點暈,這是什麼鬼,沒關系,我們通過幾個例子,帶你真正的了解和使用它
例一:給一個數組,選出數組中所有大于5的數
相信看完這個例子後,會有一些小夥伴明白什麼是布爾型索引了吧,而且很使用,因為實際的資料的過濾、篩選中都會碰到這樣類似的問題,numpy簡單、直接、高效的可以輕松解決這個問題。
明白了它的文法是怎麼一回事了,那你知道他的原理嗎?
在解釋他的原理之前,先看兩個東西
第一: 我們在文章的開頭就提到了ndarray有一個特點,可以進行各種運算,支援+-*/操作,對數組中的每個元素都進行相應的操作,同時它也支援 > < 等操作,結果傳回bool值
看到這裡,你是不是有一種似懂非懂的感覺呢,不要急,請看第二
第二: 看下圖
解釋:将同樣大小的布爾數組傳進索引,會傳回一個由所有True對應位置上元素的數組
綜合上述兩點,這就是 a[a>5]的原理,也是布爾型索引的原理
例二 : 給一個數組,選出數組中所有大于5的偶數
兩種方法: 複雜的麻煩的方法:
推薦方法:
例三: 給一個數組,選出數組中所有大于5的數和偶數
例四 : 給一個數組,選出數組中所有不大于5的數
numpy的花式索引
懵逼了吧,看例子
例一: 對于一個數組,選出其第1,3,4,6,7個元素,組成新的數組
解釋:将一個包含有對應元素所在位置的索引(整數)的數組傳進索引,會傳回一個由所有對應位置上元素的數組
例二: 對于一個二維數組,選出其第一列和第三列,組成新的二維數組
備注: 如果行或者列沒有要求,就全切,使用 [:]表示行或者列
總結一下,上面我們總共羅列出了四種方式,正常的切片,正常的索引,布爾值索引,花式索引四種,這四種對于多元的數組,可以混合搭配使用
比如:
補充:特别注意,使用花式索引時,如果兩邊都是花式索引,會出問題,或者報錯
兩邊都為花式索引時,就會換一種解析的方式,會取出,按照類似了坐标的取法,取出 [1,2]和[3,4]這麼兩個數,而不是二維數組的形式,因為取法類似于坐标,是以兩邊使用花式索引時,要保證兩邊的個數時一樣的。
那我們就想這麼取,而且還能達到我們想要的結果,怎麼辦?
思路:分兩步, 先切行,再切列
numpy通用函數
通用函數:能同時對數組中所有元素進行運算的函數,即能夠批量運算
常見的通用函數:
一進制函數(函數中傳一個參數的就是一進制函數):
abs:取絕對值
sqrt:開根号
exp: 指數
log:對數
ceil:向上取整
floor:向下取整
rint:四舍五入取整
trunc:向0取整(截斷取整)
modf:将原數組拆成兩個數組,一個放原數組的小數部分,一個放原數組的整數部分(以小數的形式)
cos,sin,tan:三角函數
isnan:判斷是不是nan類型的浮點數
備注:nan 是特殊的浮點數,但是他的語義卻是:not a number 不是一個數
特别說明:這是唯一一個自己不等于自己的類型,即 x == x 為False,那我們如何判斷一個數是不是nan呢?
判斷一個變量是不是nan的方法:
那哪些情況下的結果為nan呢? 即不合法的數,比如 對負數開根号、0/0(當然能除盡的情況下)等
isinf: 判斷是否為無窮大小數
備注:inf 也是一個特殊的浮點類型
inf這個數怎麼得來呢,整數除以無限趨近于零的數就是無限趨近inf這個數,負數就是-inf
inf這個數怎麼得來,示例如下:
補充:
nan 不等于任何浮點數 inf(infinity)比任何浮點數都大
numpy中建立特殊值:np.nan,np.inf ,建立-inf為:np.NINF
在資料分析中,nan常被用作表示資料缺失值
一個數組,怎麼過濾掉nan或inf呢,直接使用布爾型索引
二進制函數(函數中傳兩個參數的就是二進制函數):
add(加) substract(減) multiply(乘) divide(除) power(乘方) mod(取模)
maximum minimum 兩個相同長度的數組中批量性的一一對應的取最大或者最小
numpy中的數學和統計方法
np.sum() 求和 np.cumsum() 求字首和或累計和 np.mean() 求平均數 np.std() 求标準差 np.var() 求方差
np.min() 求最小值 np.max() 求最大值 np.argmin() 求最小值索引 np.argmax()求最大值索引
這些方法中重點說cumsum ---字首和,那什麼是字首和,就是一個數組中對應的位置上之前的所有數的和。
有的同學肯定會問這樣的方法有什麼用呢?
比如這樣一個場景,求出這個數組中第3個數到第7個數之前數的和
這樣的問題我們會怎麼做,for循環或者切片,在求和,時間複雜度O(n),而cumsum方法貌似時間複雜度也是O(n)啊,沒有感覺快啊,但是,如果這樣的請求有k個,那我們之前的方法的時間複雜度就是O(nk)了。
所有,cumsum主要用于求一段區間的和, b[7]-b[3-1]
方差和标準差, 标準差是方差開根号,方差是一堆數的平均數與每一個數相減的平方和在除以這堆數的長度
Numpy的随機數
熟悉python的小夥伴都知道python中的标準庫random子產品,用來生成随機數,那numpy中的random有什麼作用呢?
numpy中的random支援批量生成随機數
numpy中的random是numpy的一個子包,用法跟python中的random幾乎一樣。
那它們不一樣的是啥呢?
首先,在python中 生成随機(0,1)之間小數的方法為 random.random(),而numpy中為 numpy.random.rand(),但是numpy的rand中支援出入一個數字,用于批量生成多個随機小數
那如何批量生成多元數組呢? 很簡單,多傳參數即可 ,比如,批量生成二維的數組為 numpy.random.rand(10,8)
其他用法:
np.random.randint(m,n) 随機生成m到n的整數
np.random.randint(m,n,k) 随機生成k個m到n的整數
np.random.randint(m,n,(k,j)) 随機生成k行j列的m到n的整數的二維數組
小結:
np.random中其他的用法跟np.random.randint類似,對傳一個參數,表示批量生成對個随機數(一維的),傳一個元組,表示批量生成二維的
作者:趙盼盼
出處:https://www.cnblogs.com/zhaopanpan/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
⇩ 關注或點個喜歡就行 ^_^
關注我