NumPy?與?Python?內(nèi)置列表計(jì)算標(biāo)準(zhǔn)差區(qū)別詳析
1 什么是 Numpy
NumPy,是 Numerical Python 的簡(jiǎn)稱(chēng),用于高性能科學(xué)計(jì)算和數(shù)據(jù)分析的基礎(chǔ)包,像數(shù)學(xué)科學(xué)工具(pandas)和框架(Scikit-learn)中都使用到了 NumPy 這個(gè)包。
NumPy 中的基本數(shù)據(jù)結(jié)構(gòu)是ndarray
或者 N 維數(shù)值數(shù)組,在形式上來(lái)說(shuō),它的結(jié)構(gòu)有點(diǎn)像 Python 的基礎(chǔ)類(lèi)型——Python列表。
但本質(zhì)上,這兩者并不同,可以看到一個(gè)簡(jiǎn)單的對(duì)比。
我們創(chuàng)建兩個(gè)列表,當(dāng)我們創(chuàng)建好了之后,可以使用 +
運(yùn)算符進(jìn)行連接:
list1 = [i for i in range(1,11)] list2 = [i**2 for i in range(1,11)] print(list1+list2) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
列表中元素的處理感覺(jué)像對(duì)象,不是很數(shù)字,不是嗎? 如果這些是數(shù)字向量而不是簡(jiǎn)單的數(shù)字列表,您會(huì)期望 + 運(yùn)算符的行為略有不同,并將第一個(gè)列表中的數(shù)字按元素添加到第二個(gè)列表中的相應(yīng)數(shù)字中。
接下來(lái)看一下 Nympy 的數(shù)組版本:
import numpy as np arr1 = np.array(list1) arr2 = np.array(list2) arr1 + arr2 # array([ 2, 6, 12, 20, 30, 42, 56, 72, 90, 110])
通過(guò) numpy 的np.array
數(shù)組方法實(shí)現(xiàn)了兩個(gè)列表內(nèi)的逐個(gè)值進(jìn)行相加。
我們通過(guò)dir
函數(shù)來(lái)看兩者的區(qū)別,先看 Python 內(nèi)置列表 list1
的內(nèi)置方法:
再用同樣的方法看一下 arr1中的方法:
NumPy 數(shù)組對(duì)象還有更多可用的函數(shù)和屬性。 特別要注意諸如mean
、std
和sum
之類(lèi)的方法,因?yàn)樗鼈兦宄乇砻髦攸c(diǎn)關(guān)注使用這種數(shù)組對(duì)象的數(shù)值/統(tǒng)計(jì)計(jì)算。 而且這些操作也很快。
2 NumPy 數(shù)組和 Python 內(nèi)置計(jì)算對(duì)比
NumPy 的速度要快得多,因?yàn)樗氖噶炕瘜?shí)現(xiàn)以及它的許多核心例程最初是用 C 語(yǔ)言(基于 CPython 框架)編寫(xiě)的。 NumPy 數(shù)組是同構(gòu)類(lèi)型的密集排列的數(shù)組。 相比之下,Python 列表是指向?qū)ο蟮闹羔様?shù)組,即使它們都屬于同一類(lèi)型。 因此,我們得到了參考局部性的好處。
許多 NumPy 操作是用 C 語(yǔ)言實(shí)現(xiàn)的,避免了 Python 中的循環(huán)、指針間接和逐元素動(dòng)態(tài)類(lèi)型檢查的一般成本。 特別是,速度的提升取決于您正在執(zhí)行的操作。 對(duì)于數(shù)據(jù)科學(xué)和 ML 任務(wù),這是一個(gè)無(wú)價(jià)的優(yōu)勢(shì),因?yàn)樗苊饬碎L(zhǎng)和多維數(shù)組中的循環(huán)。
讓我們使用 @timing
計(jì)時(shí)裝飾器來(lái)說(shuō)明這一點(diǎn)。 這是一個(gè)圍繞兩個(gè)函數(shù) std_dev
和std_dev_python
包裝裝飾器的代碼,分別使用 NumPy 和本機(jī) Python 代碼實(shí)現(xiàn)列表/數(shù)組的標(biāo)準(zhǔn)差計(jì)算。
3 函數(shù)計(jì)算時(shí)間裝飾器
我們可以使用 Python 裝飾器和functools
模塊的wrapping
來(lái)寫(xiě)一個(gè) 時(shí)間裝飾器timing
:
def timing(func): @wraps(func) def wrap(*args, **kw): begin_time = time() result = func(*args, **kw) end_time = time() print(f"Function '{func.__name__}' took {end_time-begin_time} seconds to run") return result return wrap
4 標(biāo)準(zhǔn)差計(jì)算公式
然后利用這個(gè)時(shí)間裝飾器來(lái)看 Numpy 數(shù)組和 Python 內(nèi)置的列表,然后計(jì)算他們的標(biāo)準(zhǔn)差,
公式如圖:
- 定義 Numpy 計(jì)算標(biāo)準(zhǔn)差的函數(shù)
std_dev()
,numpy
模塊中內(nèi)置了標(biāo)準(zhǔn)差公式的函數(shù)a.std()
,我們可以直接調(diào)用 - 列表計(jì)算公式方法需要按照公式一步一步計(jì)算:
- 先求求出宗和
s
- 然后求出平均值
average
- 計(jì)算每個(gè)數(shù)值與平均值的差的平方,再求和
sumsq
- 再求出
sumsq
的平均值sumsq_average
- 得到最終的標(biāo)準(zhǔn)差結(jié)果
result
代碼如下:
from functools import wraps from time import time import numpy as np from math import sqrt def timing(func): @wraps(func) def wrap(*args, **kw): begin_time = time() result = func(*args, **kw) end_time = time() # print(f"Function '{func.__name__}' with arguments {args},keywords {kw} took {end_time-begin_time} seconds to run") print(f"Function '{func.__name__}' took {end_time-begin_time} seconds to run") return result return wrap @timing def std_dev(a): if isinstance(a, list): a = np.array(a) s = a.std() return s @timing def std_dev_python(lst): length = len(lst) s = sum(lst) average = s / length sumsq = 0 for i in lst: sumsq += (i-average)**2 sumsq_average = sumsq/length result = sqrt(sumsq_average) return result
運(yùn)行結(jié)果,最終可以看到 1000000 個(gè)值得標(biāo)準(zhǔn)差的值為 288675.13459,而 Numpy 計(jì)算時(shí)間為 0.0080 s,而 Python 原生計(jì)算方式為 0.2499 s:
由此可見(jiàn),Numpy 的方式明顯更快。
5 總結(jié)
NumPy 是專(zhuān)門(mén)針對(duì)數(shù)組的操作和運(yùn)算進(jìn)行了設(shè)計(jì),所以數(shù)組的存儲(chǔ)效率和輸入輸出性能遠(yuǎn)優(yōu)于Python中的嵌套列表,數(shù)組越大,NumPy的優(yōu)勢(shì)就越明顯。
到此這篇關(guān)于NumPy 與 Python 內(nèi)置列表計(jì)算標(biāo)準(zhǔn)差區(qū)別詳析的文章就介紹到這了,更多相關(guān)Python 內(nèi)置列表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)求兩個(gè)數(shù)組交集的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)求兩個(gè)數(shù)組交集的方法,涉及Python數(shù)組遍歷、排序、判斷、追加等相關(guān)操作技巧,需要的朋友可以參考下2019-02-02一篇文章弄懂Python中所有數(shù)組數(shù)據(jù)類(lèi)型
這篇文章主要給大家介紹了關(guān)于Python中所有數(shù)組數(shù)據(jù)類(lèi)型的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06python 處理數(shù)字,把大于上限的數(shù)字置零實(shí)現(xiàn)方法
今天小編就為大家分享一篇python 處理數(shù)字,把大于上限的數(shù)字置零實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01用pywin32實(shí)現(xiàn)windows模擬鼠標(biāo)及鍵盤(pán)動(dòng)作
這篇文章主要介紹了用pywin32實(shí)現(xiàn)windows模擬鼠標(biāo)及鍵盤(pán)動(dòng)作的示例,需要的朋友可以參考下2014-04-04pytorch?液態(tài)算法實(shí)現(xiàn)瘦臉效果
在PS中,我們可以利用液化工具對(duì)人像進(jìn)行形變處理,例如瘦臉、瘦腿、放大眼睛等一系列的常規(guī)操作。今天我們來(lái)了解一下這些操作的算法原理,并用pytorch來(lái)實(shí)現(xiàn)瘦臉效果2021-11-11python讀取文本中數(shù)據(jù)并轉(zhuǎn)化為DataFrame的實(shí)例
下面小編就為大家分享一篇python讀取文本中數(shù)據(jù)并轉(zhuǎn)化為DataFrame的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04Python區(qū)塊鏈創(chuàng)建Block Class教程
這篇文章主要為大家介紹了Python區(qū)塊鏈創(chuàng)建Block Class教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05python pow函數(shù)的底層實(shí)現(xiàn)原理介紹
這篇文章主要介紹了python pow函數(shù)的底層實(shí)現(xiàn)原理介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03