如果只是從事簡單的數(shù)據(jù)分析困后,其實(shí)numpy的用處并不是很大澈灼。簡單了解一下numpy絮缅,學(xué)好pandas已經(jīng)夠用怎燥,尤其是對于結(jié)構(gòu)化或表格化數(shù)據(jù)负饲。但是精通面向數(shù)組的編程和思維方式是成為python科學(xué)計(jì)算牛人的關(guān)鍵一步堤魁。
而且使用numpy的代碼往往比普通數(shù)組要快,因?yàn)閿?shù)組運(yùn)算一般都比純python循環(huán)要快得多返十。大量使用列表妥泉,將無可避免的使用循環(huán)。
當(dāng)大家對numpy足夠熟悉的時候洞坑,我建議大家這樣做:
- 將python循環(huán)和條件邏輯轉(zhuǎn)換為數(shù)組運(yùn)算和布爾數(shù)組運(yùn)算盲链。
- 盡量使用廣播。
- 避免復(fù)制數(shù)據(jù)迟杂,盡量使用數(shù)組視圖刽沾,即切片。
- 利用ufunc及其它各種方法排拷。
線性代數(shù)
import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[6, 23], [-1, 7], [8, 9]])
print(x)
print(y)
print(x.dot(y))
這是最基礎(chǔ)的矩陣計(jì)算侧漓。比較常用的矩陣計(jì)算函數(shù)如下。
函數(shù) | 說明 |
---|---|
diag | 以一位數(shù)組形式返回對角線元素 |
dot | 矩陣乘法 |
trace | 矩陣跡 |
det | 行列式值 |
eig | 本征值與本征向量 |
inv | 求逆 |
pinv | Moore-Penrose偽逆 |
qr | QR分解 |
svd | 奇異值分解 |
solve | 解線性方程組Ax=b |
lstsq | 計(jì)算Ax=b的最小二乘解 |
高級數(shù)據(jù)操作
ndarray數(shù)組視圖不復(fù)制任何數(shù)據(jù)的原因是因?yàn)楣テ茫琻darray不只是一塊內(nèi)存和一個dtype火架,更準(zhǔn)確的說它還有跨度信息,這使得數(shù)組能以各種步幅在內(nèi)存中移動忙菠。(其實(shí)移動的是指針)也因此何鸡,ndarray數(shù)組有很多我們意想不到的功能。
import numpy as np
arr = np.arange(8)
print(arr)
new_arr = arr.reshape((4, 2))
print(arr)
print(new_arr)
同樣牛欢,既然可以重塑骡男,那也可以扁平化,即展開傍睹。
import numpy as np
arr = np.arange(8)
new_arr = arr.reshape((4, 2))
print(new_arr)
new_new_arr = new_arr.ravel()
print(new_new_arr)
在這里要提及一點(diǎn)隔盛。與其他科學(xué)計(jì)算環(huán)境相反(R或matlab),numpy允許更為靈活地控制數(shù)據(jù)在內(nèi)存中的布局犹菱。具體來說,比如展開數(shù)組時是按列優(yōu)先還是按行優(yōu)先吮炕。
pandas的操作對象主要是結(jié)構(gòu)化數(shù)據(jù)腊脱,numpy的操作對象主要是ndarray數(shù)組。這兩者之間有很多功能函數(shù)是一一對應(yīng)的龙亲,比如陕凹,pandas有對表格的拼接,ndarray也有對數(shù)組的拼接鳄炉。
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10 ,11, 12]])
print(np.concatenate([arr1, arr2], axis=0))
print(np.concatenate([arr1, arr2], axis=1))
有拼接就有拆分杜耙,split函數(shù)用于將一個數(shù)組沿指定軸拆分為多個數(shù)組。
import numpy as np
from numpy.random import randn
arr = randn(8, 2)
first, second, third = np.split(arr, [2, 3])
print(first)
print(second)
print(third)
還有很多功能不一一介紹拂盯,其實(shí)非常簡單佑女,在這里只是引起大家注意,知道numpy功能的強(qiáng)大谈竿。
還需要注意一點(diǎn)的是团驱,這些函數(shù)都是建立在ndarray數(shù)組之上的,列表榕订,元組等并無此功能店茶。
廣播機(jī)制
所謂廣播是說不同形狀的數(shù)組之間的算術(shù)運(yùn)算的執(zhí)行方式蜕便。
將標(biāo)量值和數(shù)組進(jìn)行組合時就會發(fā)生最簡單的廣播劫恒。
import numpy as np
arr = np.arange(5)
print(arr)
print(arr-1)
如圖所示,當(dāng)數(shù)組和數(shù)字之間運(yùn)算時轿腺,并沒有報錯两嘴,而是每個數(shù)組元素和該數(shù)字做了運(yùn)算。這在很多科研數(shù)據(jù)處理的時候族壳,會方便很多憔辫。
ufunc高級應(yīng)用
ufunc除了一些通用的施行特定矢量化運(yùn)算的特殊方法外,還可以自定義函數(shù)對數(shù)組進(jìn)行運(yùn)算仿荆。
import numpy as np
def add_elements(x, y):
return x + y
add_them = np.frompyfunc(add_elements, 2, 1)
print(add_them(np.arange(8), np.arange(8)))
當(dāng)然贰您,不幸的是,這種創(chuàng)造ufunc的手段雖然很靈活拢操,卻非常慢锦亦。因?yàn)樗鼈冊谟?jì)算的時候都要執(zhí)行一次python函數(shù)調(diào)用,這自然會比numpy自帶的基于C編寫的ufunc慢很多令境。
為此杠园,python科學(xué)計(jì)算社區(qū)正在開發(fā)一些項(xiàng)目,力求使自定義ufunc的性能接近內(nèi)置的那些舔庶。