numpy——科學計算庫的講解(一)
QQ:3020889729 小蔡
本節主要講解numpy的效率以及基本對象概念,剩下兩個部分在另外的博客中展開講解。
· numpy效率以及基本對象概念(√)
· numpy基本運算函數(×)
· numpy基本練習(×)
(本文淺薄,意在闡述爲什麼選擇科學計算庫——numpy效率以及基本屬性概念)
本文以jupyter notebook格式展開~
說明:代碼部分爲jupyter notebook內書寫的代碼,而黃色標註部分爲notebook輸出結果。
第一部分:numpy的基本對象
import numpy as np
創建不同的產生數組的方法函數——進行比對
def Add_array(n):
'''用python原生庫創建數組和進行數組加法
返回一個列表
'''
a = [i**2 for i in range(n)] # 列表推導式
b = [i**3 for i in range(n)]
c = []
for i in range(n):
c.append(a[i]+b[i]) # 實現元素相加——如果直接a+b只會將所有元素相連
return c
def Add_narray(n):
'''用numpy的庫函數進行創建和運算
返回一個narray對象
'''
a = np.arange(n)**2 # 創建一個range的ndarray對象:與[i**2 for i in range(n)] 顯示的結果相同,性能有所不同
b = np.arange(n)**3
c = a+b # 元素按位相加
return c
創建對應方法下的數組——並輸出查看效果
orgin_array = Add_array(10)
orgin_array
[0, 2, 12, 36, 80, 150, 252, 392, 576, 810]
numpy_narray = Add_narray(10)
numpy_narray
array([ 0, 2, 12, 36, 80, 150, 252, 392, 576, 810], dtype=int32)
體驗一下numpy的五個基本屬性:
· ndarray.ndim——數組的軸數(尺寸或者說維度)
· ndarray.shape——數組形狀
· ndarray.size——數組大小/元素個數
· ndarray.dtype——元素數據類型
· ndarray.itemsize——元素所佔字節數/元素字節大小
· ndarray.data——數組的元素緩衝區——一般直接使用索引,不使用它
numpy_narray.ndim
1
軸數爲1,即一維數組
numpy_narray.shape
(10,)
形狀爲(10, ),是指一維的元素個數爲10個或者說第一軸上有十個元素
(同時這裏也說明了,創建指定形狀的數組時,如果爲一維,應該鍵入元組中包含維度大小以外的數據外還要添加一個逗號)
numpy_narray.size
10
數組的大小爲10,以爲這這個數組一共含有10個元素
numpy_narray.dtype
dtype(‘int32’)
數組的數據類型爲int32
numpy_narray.itemsize
4
單個元素的字節大小爲4——即int32,32位的整型數據大小爲4個字節
numpy_narray.data
<memory at 0x000002BC4EAD6648>
說明了數組存儲所在,緩衝區的地址
嘗試定義創建的數組的數據類型和形狀
example_1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=np.float32).reshape(3, 3) # 傳入爲1維列表元素
example_1
array([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]], dtype=float32)
- 從example_1知曉,通過array創建數組數據類型——而數組的內容爲傳入的列表(切記傳入數據爲序列形式,可以是元組或列表等,不可以直接傳入某個常量)
- 在創建數組時,可以對數據類型進行定義——同時可以連續加載reshape函數進行數組形狀轉換(需要注意的是,形狀之積應該爲元數個數)
example_2 = np.array([[1, 2, 3],[4, 5, 6]])
example_2
array([[1, 2, 3],
[4, 5, 6]])
從example_2知曉,傳入array的list如果是多爲列表,那麼創建的數組也就是對應的維度大小
下面我們嘗試使用元組作爲list元素,看看是什麼結果
example_3 = np.array([(1, 2, 3),(4, 5, 6)])
example_3
array([[1, 2, 3],
[4, 5, 6]])
從example_2和example_3可以看出,傳入的list中無論是元組作爲子元素還是list作爲子元素,都會被array轉換爲對應的相同的dnarray數組的子元素
example_4 = np.array((1, 2, 3))
print("example_4 is {}".format(example_4))
example_4 is [1 2 3]
同樣的,傳入元組作爲輸入數據,也是可以的。
第二部分:體驗numpy的效率
- 使用魔法操作符%下的timeit計算運行時間 ·
- 原生python的數組運算效率 ·
- numpy的數組運算效率
對兩個含十個元素數組的創建以及這10個元素的相加
%timeit Add_array(10)
7.2 µs ± 95 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit Add_narray(10)
3.27 µs ± 141 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
10次的運算——可以看出numpy幾乎快了原生python一倍
對兩個含1000個元素數組的創建以及這1000個元素的相加
%timeit Add_array(1000)
705 µs ± 11.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit Add_narray(1000)
8.38 µs ± 21.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
可以看出——當進行大運算時,python原生計算明顯出現了效率低的問題(numpy近乎快了80多倍)
對兩個含100000個元素數組的創建以及這100000個元素的相加
%timeit Add_array(100000)
71.9 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit Add_narray(100000)
369 µs ± 6.22 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
當進行10萬次運算時,基本上就可以發現,直接使用原生python進行運算時效率是不客觀的(numpy還在微妙級,而原生的python卻到了ms級)
這裏可以看出,當進行較大運算時,我們應該採用numpy一類的科學運算庫。
因爲這些計算庫既方便我們的使用,避免構建新的函數或者循環就可以實現數組元素之間的計算,而且大大提高了我們的效率。
最後以對兩個含百萬個元素數組的創建以及這百萬個元素的相加
%timeit Add_array(1000000)
817 ms ± 19.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit Add_narray(1000000)
10.6 ms ± 89 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
可以看出,numpy的運算確實要比原生python快得多。
需要說明的是,不要嘗試使用原生python對千萬級以上的運算進行求解——那樣花的時間會很長很長,而使用科學計算庫則可能較好的解決問題。
(原嘗試億級運算,但是cpu很快就上去了,而且等了一會兒也沒有結果,所以希望大家在進行計算大數據時,儘量使用各種各樣的科學計算庫)
嘗試一下使用numpy進行千萬級運算
%timeit Add_narray(10000000)
115 ms ± 257 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
嘗試一下使用numpy進行億級運算
%timeit Add_narray(100000000)
1.17 s ± 5.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
科學計算庫計算很快,但是千萬不要因爲前面的數據顯示numpy僅僅比原生python運算快了100倍左右,就去嘗試用原生python計算大數據(千萬級以上的運算)
效率真的不容樂觀(如有興趣,可以測試以下千萬級原生運算: %timeit Add_array(10000000))
最後做一個總結:
- numpy科學計算庫的使用方法還是比較簡單的——這裏僅僅是採用arange創建連續元素數組。
- numpy創建的元素可直接用於多個數組元素與元素直接的加減乘除。
- numpy的效率比python原生運算快,而且使用方便。
- 所以說numpy被用於衆多的人工智能運算,與大數據處理是有原因的——效率是成功的一部分。
以上就是關於numpy效率和基本屬性的展示和簡單探索。(此處提示,如果感興趣,可以對tensorflow等中的numpy運算進行時間估計。)