第4章 NumPy基礎(chǔ)(3)

以下內(nèi)容主要學(xué)習(xí)自《利用Python進(jìn)行數(shù)據(jù)分析》

第4章 NumPy基礎(chǔ)(3)

NumPy是Numerical Python的簡稱,它是目前Python數(shù)值計(jì)算中最為重要的基礎(chǔ)包。大多數(shù)計(jì)算包都提供了基于Numpy的科學(xué)函數(shù)功能,將NumPy的數(shù)組對(duì)象作為數(shù)據(jù)交換的通用語言。

本章將介紹NumPy數(shù)組的基礎(chǔ)操作。雖然深入理解NumPy對(duì)于大部分?jǐn)?shù)據(jù)分析應(yīng)用并不是必需的,但是精通基于數(shù)組的編程和思維是成為Python科學(xué)計(jì)算專家的第一步

NumPy-3

ndarray運(yùn)算

單數(shù)組的算術(shù)

掌握NumPy數(shù)組之所以重要,是因?yàn)樗试S你進(jìn)行批量操作而不需任何for循環(huán)。NumPy稱這種特性為向量化。

標(biāo)量算術(shù)

所謂的標(biāo)量,簡單理解就是具體數(shù)值。數(shù)組與標(biāo)量的算術(shù)操作(加減乘除),會(huì)影響到數(shù)組的每一個(gè)元素。

In [10]: arr = np.arange(12).reshape(3,4)

In [12]: arr
Out[12]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [11]: arr + 1
Out[11]:
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

In [13]: arr * 0.5
Out[13]:
array([[0. , 0.5, 1. , 1.5],
       [2. , 2.5, 3. , 3.5],
       [4. , 4.5, 5. , 5.5]])
一元通用函數(shù)

假設(shè)x是一個(gè)ndarray數(shù)組,那么下面的一元通用函數(shù)會(huì)影響到數(shù)組中的每一個(gè)元素。

函數(shù)名 描述
np.abs(x) 絕對(duì)值
np.sqrt(x) 平方根
np.square(x) 平方
np.exp(x) 自然指數(shù)
np.[log|log10|log2](x) 對(duì)數(shù)
np.sign(x) 符號(hào)值(1正數(shù)、0零、-1負(fù)數(shù))
np.ceil(x) 最大整數(shù)值
np.floor(x) 最小整數(shù)值
np.[sin|cos|tan](x) 三角函數(shù)
np.[arcsin|arccos|arctan](x) 反三角函數(shù)
np.isnan(x) 是否NaN

同尺寸數(shù)組的算術(shù)

任何在兩個(gè)等尺寸數(shù)組之間的算術(shù)操作都應(yīng)用了逐元素操作的方式。

四則運(yùn)算

可以對(duì)兩個(gè)數(shù)組直接應(yīng)用四則運(yùn)算:

# 生成隨機(jī)數(shù)組1
In [1]: arr1 = np.random.randint(low=0, high=20, size=(2,5))

In [2]: arr1
Out[2]:
array([[14, 12,  7,  5,  6],
       [13,  2,  3, 15,  7]])

# 生成隨機(jī)數(shù)組2
In [3]: arr2 = np.random.randint(low=0, high=20, size=(2,5))

In [4]: arr2
Out[4]:
array([[ 9,  0,  4, 19, 16],
       [11,  9, 17,  3,  3]])

# 兩個(gè)同尺寸數(shù)組相加
In [5]: arr1+arr2
Out[5]:
array([[23, 12, 11, 24, 22],
       [24, 11, 20, 18, 10]])

# 兩個(gè)同尺寸數(shù)組相減
In [6]: arr1-arr2
Out[6]:
array([[  5,  12,   3, -14, -10],
       [  2,  -7, -14,  12,   4]])

# 兩個(gè)同尺寸數(shù)組相乘
In [7]: arr1 * arr2
Out[7]:
array([[126,   0,  28,  95,  96],
       [143,  18,  51,  45,  21]])

# 兩個(gè)同尺寸數(shù)組相除(注意,當(dāng)被0除時(shí),會(huì)有一個(gè)警告、但不會(huì)報(bào)錯(cuò))
In [8]: arr1/arr2
RuntimeWarning: divide by zero encountered in true_divide
Out[8]:
array([[1.55555556,        inf, 1.75      , 0.26315789, 0.375     ],
       [1.18181818, 0.22222222, 0.17647059, 5.        , 2.33333333]])
比較運(yùn)算

同尺寸數(shù)組之間的比較,會(huì)產(chǎn)生一個(gè)布爾值數(shù)組:

In [9]: arr1
Out[9]:
array([[14, 12,  7,  5,  6],
       [13,  2,  3, 15,  7]])

In [10]: arr2
Out[10]:
array([[ 9,  0,  4, 19, 16],
       [11,  9, 17,  3,  3]])
       
In [11]: arr1>arr2
Out[11]:
array([[ True,  True,  True, False, False],
       [ True, False, False,  True,  True]])
二元通用函數(shù)

假設(shè)x, y是同尺寸的ndarray數(shù)組,那么下面的二元通用函數(shù)會(huì)逐元素的進(jìn)行運(yùn)算。

函數(shù)名 描述
np.add(x, y) 兩個(gè)數(shù)組相加
np.subtractx, y) 兩個(gè)數(shù)組相減
np.multiply(x, y) 兩個(gè)數(shù)組相乘
np.divide(x, y) 兩個(gè)數(shù)組相除
np.floor_divide(x, y) 兩個(gè)數(shù)組整除(放棄余數(shù))
np.power(x, y) 將第二個(gè)數(shù)組作為第一個(gè)數(shù)組的冪次方
np.[maximum|fmax](x, y) 逐元素計(jì)算最大值,fmax忽略NaN
np.[minimum|fmin](x, y) 逐元素計(jì)算最小值,fmin忽略NaN
np.mod(x, y) 按元素求模,即求相除后的余數(shù)
np.copysign(x, y) 將第一個(gè)數(shù)組的符號(hào)改為第二個(gè)數(shù)組的符號(hào)(正負(fù)號(hào))
np.[greater|greater_equal](x, y) 比較兩個(gè)數(shù)組,返回布爾值數(shù)組
np.[less|less_equal](x, y) 比較兩個(gè)數(shù)組,返回布爾值數(shù)組
np.[equal|not_equal](x, y) 比較兩個(gè)數(shù)組,返回布爾值數(shù)組
np.logical_and(x, y) 邏輯與
np.logical_or(x, y) 邏輯或
np.logical_xor(x, y) 邏輯異或

條件邏輯算術(shù)

NumPy的np.where函數(shù)是三元表達(dá)式x if condition eles y的向量化版本。在詳細(xì)解釋where之前,我們先看看如下的示例代碼:

In [1]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])

In [2]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])

In [3]: cond = np.array([True, False, True, True, False])

假設(shè)cond中的元素為True時(shí),我們?nèi)arr中的對(duì)應(yīng)元素,否則取yarr中的對(duì)應(yīng)元素。常規(guī)情況下我們使用列表推導(dǎo)式來完成,如下:

In [3]: result = [(x if c else y)
    ...: for x, y, c in zip(xarr, yarr, cond)]

In [4]: result
Out[4]: [1.1, 2.2, 1.3, 1.4, 2.5]

以上雖然到達(dá)了目的,但有兩個(gè)問題:首先,如果數(shù)組很大的話,速度會(huì)很慢(因?yàn)樗械墓ぷ鞫际峭ㄟ^Python的解釋器完成的);其次,當(dāng)數(shù)組是多維時(shí)就無法奏效了。此時(shí),np.where就派上用場(chǎng)了。

In [5]: result = np.where(cond, xarr, yarr)

In [6]: result
Out[6]: array([1.1, 2.2, 1.3, 1.4, 2.5])

另外,np.where的第二個(gè)和第三個(gè)參數(shù)除了是數(shù)組,還可以是標(biāo)量。假設(shè)我們有一個(gè)數(shù)組,我們想把其中正值都替換為2、負(fù)值都替換為-2,那么代碼如下:

# 創(chuàng)建一個(gè)2X3的隨機(jī)數(shù)數(shù)組
In [1]: arr = np.random.randn(2, 3)

In [2]: arr
Out[2]:
array([[-0.43739758,  0.96547377,  0.15388708],
       [-1.49166677, -1.19171251, -0.15982192]])

# 逐元素比較arr是否大于零,結(jié)果作為條件
# 為True,就賦值2
# 為False,就賦值-2
In [3]: np.where(arr>0, 2, -2)
Out[3]:
array([[-2,  2,  2],
       [-2, -2, -2]])

不同尺寸數(shù)組的操作:廣播特性

ndarray統(tǒng)計(jì)方法

NumPy提供了如下的統(tǒng)計(jì)方法(聚合函數(shù))

方法 描述
sum 累計(jì)和
mean 求平均值
std, var 求標(biāo)準(zhǔn)差、方差
min, max 求最大值、最小值
argmin, argmax 求最大值、最小值出現(xiàn)的位置
cumsum 計(jì)算累計(jì)值
cumprod 計(jì)算累計(jì)積

注意:以上的方法既可以調(diào)用ndarray實(shí)例的方法(arr.sum()),也可以使用NumPy頂層的函數(shù)(np.sum(arr))。

# 創(chuàng)建一個(gè)最小值-5、最大值5的3X4的隨機(jī)數(shù)組
In [1]: arr = np.random.randint(-5,5,(3, 4))

In [2]: arr
Out[2]:
array([[ 1,  0,  3, -1],
       [ 0,  0,  0,  2],
       [ 0, -2,  3,  2]])

# 對(duì)數(shù)組求和,此處是調(diào)用實(shí)例的方法來求和的。
In [3]: arr.sum()
Out[3]: 8

# 與上面的效果相同,但此處是調(diào)用NumPy的頂層函數(shù)來求和的。
In [4]: np.sum(arr)
Out[4]: 8

上面列出的統(tǒng)計(jì)方法(聚合函數(shù)),均有可選參數(shù)axis。如果不指定這個(gè)參數(shù),那么就是對(duì)所有的元素進(jìn)行聚合運(yùn)算。如果為axis參數(shù)指定值,就是在給定軸上進(jìn)行聚合運(yùn)算,并得到下降一個(gè)維度的數(shù)組。

In [5]: arr
Out[5]:
array([[ 1,  0,  3, -1],
       [ 0,  0,  0,  2],
       [ 0, -2,  3,  2]])

# 求整個(gè)數(shù)組的最大值
In [6]: np.max(arr)
Out[6]: 3

# 在0軸上求最大值(按行)
In [7]: np.max(arr, axis=0)
Out[7]: array([1, 0, 3, 2])

# 在1軸上求最大值(按列)
In [8]: np.max(arr, axis=1)
Out[8]: array([3, 2, 3])

ndarray集合操作

獲取唯一值

獲取唯一值的準(zhǔn)確說法是“獲取不重復(fù)的值”,如下:

# 創(chuàng)建隨機(jī)數(shù)數(shù)組,每個(gè)元素介于0~5,共有10個(gè)元素。
In [1]: arr = np.random.randint(0, 5, (10,))

In [2]: arr
Out[2]: array([2, 1, 3, 1, 0, 2, 3, 3, 0, 2])

In [3]: np.unique(arr)  # 獲取不重復(fù)的元素
Out[3]: array([0, 1, 2, 3])

計(jì)算交集/并集

# 創(chuàng)建隨機(jī)數(shù)數(shù)組,每個(gè)元素介于0~5,共有10個(gè)元素。
In [1]: arr1 = np.random.randint(0, 5, (10,))

In [2]: arr1
Out[2]: array([2, 1, 4, 0, 2, 0, 3, 4, 2, 0])

# 創(chuàng)建隨機(jī)數(shù)數(shù)組,每個(gè)元素介于3~8,共有10個(gè)元素。
In [3]: arr2 = np.random.randint(3, 8, (10,))

In [4]: arr2
Out[4]: array([5, 3, 7, 3, 6, 6, 6, 7, 6, 7])

# 計(jì)算兩個(gè)數(shù)組的交集
In [5]: np.intersect1d(arr1, arr2)
Out[5]: array([3])

# 計(jì)算兩個(gè)數(shù)組的交集
In [6]: np.union1d(arr1, arr2)
Out[6]: array([0, 1, 2, 3, 4, 5, 6, 7])

計(jì)算包含關(guān)系

In [1]: arr = np.array([2, 1, 4, 0, 2, 0, 3, 4, 2, 0])

In [2]: np.in1d(arr, [1, 3, 5])
Out[2]:
array([False, True, False, False, False, False,  True, False, False,
       False])

集合操作函數(shù)

函數(shù) 描述
np.unique(x) 計(jì)算唯一值,并排序
np.intersect1d(x, y) 計(jì)算交集,并排序
np.union1d(x, y) 計(jì)算并集,并排序
np.in1d(x, y) 計(jì)算x的元素是否包含在y中,返回布爾數(shù)組
np.setdiff1d(x, y) 計(jì)算差集,在x中但不在y中元素
np.setxor1d(x, y) 計(jì)算異或集,在x或y中、但不屬于xy交集的元素

線性代數(shù)

在NumPy中,使用dot方法計(jì)算矩陣的點(diǎn)積。

In [1]: x = np.array([[1.,2., 3.], [4., 5., 6.]])

In [3]: y = np.array([[6.,2], [-1., 7], [3, 1]])

In [3]: x.dot(y)
Out[3]:
array([[13., 19.],
       [37., 49.]])

In [4]: np.dot(x, y)
Out[4]:
array([[13., 19.],
       [37., 49.]])

Numpy的numpy.linalg模塊擁有矩陣分解的標(biāo)準(zhǔn)函數(shù)集。

函數(shù) 描述
diag 將一個(gè)矩陣的對(duì)角元素作為一維數(shù)組返回;或?qū)⒁痪S數(shù)組轉(zhuǎn)換為矩陣
dot 矩陣點(diǎn)積
trace 計(jì)算對(duì)角元素和
det 計(jì)算矩陣的行列式
eig 計(jì)算矩陣的特征值和特征向量
inv 計(jì)算逆矩陣
pinv 計(jì)算矩陣的Moore-Penrose偽逆
qr 計(jì)算QR分解
svd 計(jì)算奇異值分解
solve 求解x的線性系統(tǒng)Ax=b,其中A是矩陣
lstsq 計(jì)算Ax=b的最小二乘解

由于線性代數(shù)的示例較復(fù)雜,所以上述標(biāo)準(zhǔn)函數(shù)庫用法,請(qǐng)參考NumPy的官方文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容