用實踐帶領你進入numpy的世界——(一):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))

最後做一個總結:

  1. numpy科學計算庫的使用方法還是比較簡單的——這裏僅僅是採用arange創建連續元素數組。
  2. numpy創建的元素可直接用於多個數組元素與元素直接的加減乘除。
  3. numpy的效率比python原生運算快,而且使用方便。
  4. 所以說numpy被用於衆多的人工智能運算,與大數據處理是有原因的——效率是成功的一部分。

以上就是關於numpy效率和基本屬性的展示和簡單探索。(此處提示,如果感興趣,可以對tensorflow等中的numpy運算進行時間估計。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章