前言
numpy
是支持 Python
語言的數(shù)值計算擴充庫,其擁有強大的高維度數(shù)組處理與矩陣運算能力。除此之外,numpy
還內(nèi)建了大量的函數(shù),方便你快速構(gòu)建數(shù)學(xué)模型。
NumPy
官網(wǎng):http://www.numpy.org/
NumPy
官網(wǎng)教程:https://docs.scipy.org/doc/numpy/user/quickstart.html
安裝及導(dǎo)入numpy
安裝numpy:
pip install numpy
導(dǎo)入numpy,推薦做法是:
import numpy as np
當(dāng)然,如果你不想像上面導(dǎo)入,你也可以和其他模塊導(dǎo)入方式一樣直接import numpy
,但還是推薦用import numpy as np
這種方式,后面用到numpy
的地方都可以用別名np
了,更加簡潔。
numpy數(shù)學(xué)中的計算
學(xué)習(xí)完后,可以熟練掌握數(shù)組各種方式的創(chuàng)建、屬性及數(shù)組操作;對矩陣的常見操作、也可以對多項式求導(dǎo)、作圖等。
1.求矩陣A的秩
提示:在線性代數(shù)中,一個矩陣A的列秩是A的線性獨立的縱列的極大數(shù)目。類似地,行秩是A的線性無關(guān)的橫行的極大數(shù)目。通俗一點說,如果把矩陣看成一個個行向量或者列向量,秩就是這些行向量或者列向量的秩,也就是極大無關(guān)組中所含向量的個數(shù)。
解析:在numpy中,求矩陣的秩用nf.linalg.matrix_rank(array)
2.求矩陣A的轉(zhuǎn)置矩陣
轉(zhuǎn)置矩陣:將矩陣的行列互換得到的新矩陣稱為轉(zhuǎn)置矩陣,轉(zhuǎn)置矩陣的行列式不變。
解析:在numpy中,求矩陣A的轉(zhuǎn)置矩陣用A.T
上面兩個問題用numpy
可快速計算出來:
import numpy as nf
A = nf.mat([[3, 2, 0, 5, 0],
[3, -2, 3, 6, -1],
[2, 0, 1, 5, -3],
[1, 6, -4, -1, 4]])
print("矩陣A:")
print(A)
print("A的秩為:{}".format(nf.linalg.matrix_rank(A)))
print("A的轉(zhuǎn)置矩陣:")
print(A.T)
運行結(jié)果:
矩陣A:
[[ 3 2 0 5 0]
[ 3 -2 3 6 -1]
[ 2 0 1 5 -3]
[ 1 6 -4 -1 4]]
A的秩為:3
A的轉(zhuǎn)置矩陣:
[[ 3 3 2 1]
[ 2 -2 0 6]
[ 0 3 1 -4]
[ 5 6 5 -1]
[ 0 -1 -3 4]]
手動求解:
3.求矩陣A的逆矩陣
說明:逆矩陣是對方陣定義的,因此逆矩陣一定是方陣。
逆矩陣:設(shè)A是數(shù)域上的一個n階矩陣,若在相同數(shù)域上存在另一個n階矩陣B,使得: AB=BA=E ,則我們稱B是A的逆矩陣,而A則被稱為可逆矩陣。注:E為單位矩陣。
解析:在numpy中,求矩陣A的轉(zhuǎn)置矩陣用A.I
import numpy as nf
A = nf.mat([[0, 1, 2],
[1, 1, 4],
[2, -1, 0]])
print("矩陣A:")
print(A)
print("A的逆矩陣:")
print(A.I)
運行結(jié)果:
矩陣A:
[[ 0 1 2]
[ 1 1 4]
[ 2 -1 0]]
A的逆矩陣:
[[ 2. -1. 1. ]
[ 4. -2. 1. ]
[-1.5 1. -0.5]]
手動計算:
4.求y = -2x^2 + 4x + 16
的根,并求出其導(dǎo)函數(shù)
解析:為了形象展示多項式,我們借用matplotlib順便繪制了該函數(shù)的圖像。后面會專門學(xué)習(xí)如何繪制,此處大概了解一下matplotlib即可。numpy中的多項式:np.poly1d(arr),需要把參數(shù)傳入。本例子中放在了一個數(shù)組中arr = np.array([-2, 4, 16])傳入的。對多項式求導(dǎo),想要求幾階導(dǎo)數(shù),只需要這里實參m傳入數(shù)字幾即可。func.deriv(m=1);定制定義域np.linspace(-4, 6, 100),這樣把-6--6之間進(jìn)行100等分,利用這些數(shù)據(jù)創(chuàng)建了一個長度為100的數(shù)組。
import numpy as np
import matplotlib.pyplot as plt
# y = -2x^2 + 4x + 16
arr = np.array([-2, 4, 16])
func = np.poly1d(arr)
# m=1表示求一階導(dǎo)數(shù),依次類推
func1 = func.deriv(m=1)
# 設(shè)置定義域-4,6;并將定義域等分了100份
x = np.linspace(-4, 6, 100)
y = func(x)
y1 = func1(x)
# 打印多項式
print(func)
# 打印多項式對應(yīng)的一階導(dǎo)數(shù)
print(func1)
# 繪制
plt.plot(x, y, label="{}".format(func))
plt.plot(x, y1, label="{}".format(func1))
plt.xlabel("x")
plt.ylabel("y")
# 顯示圖例
plt.legend()
print("多項式的根:")
print(np.roots(func))
# 顯示圖像
plt.show()
運行結(jié)果:
數(shù)組的重要屬性
numpy
的主要操作對象是同類的多維數(shù)組,即一個由相同類型元素(通常是數(shù)字)組成的、以正數(shù)為索引的數(shù)據(jù)表。在numpy
里面,維度稱為“軸”。
舉例來說,三維空間內(nèi)一點的坐標(biāo)[1,2,1]
有一個軸,三個元素,所以我們通常稱它的長度為3。在以下所示的例子中,數(shù)組有兩個軸,第一個軸的長度為2,第二個軸的長度為3。
[[ 1., 0., 0.],
[ 0., 1., 2.]]
numpy
的數(shù)組類型叫做ndarray
,也就是numpy
數(shù)組(以下簡稱為數(shù)組)。需要注意的是,numpy.array
不同于Python
標(biāo)準(zhǔn)庫中的array.array
,后者只處理一維的數(shù)組并且提供了很少的功能。一個ndarray
對象有以下一些重要的屬性:
ndarray.ndim
數(shù)組的軸的數(shù)量,即維度數(shù)量。
ndarray.shape
數(shù)組的維度。返回的是一個整數(shù)元組,指示了一個數(shù)組在各個維度的大小。對于一個n行m列的矩陣來說,它的shape
是(n,m)
。shape
的元組長度因此是軸的數(shù)量,即ndim
。
ndarray.size
數(shù)組所有元素的數(shù)量,等于shape
返回元組元素的乘積。
ndarray.dtype
一個用于描述數(shù)組元素類型的對象。可以用標(biāo)準(zhǔn)Python類型來創(chuàng)造或指定dtype
的類型。另外,Numpy也提供了自己的類型,如numpy.int32
,numpy.int16
,numpy.float64
等。
ndarray.itemsize
數(shù)組每個元素的字節(jié)大小。比如一個數(shù)組的元素為float64
,它的itemsize
為8(=64/8)
,
complex32
的itemsize
為4(=32/8)
。這個屬性等同于ndarray.dtype.itemsize
。
ndarray.data
包含了數(shù)組每個實際元素的緩沖器。一般來說我們不會用到這個屬性因為我們可以通過索引工具來獲取到數(shù)組的每個元素的值。
數(shù)組的創(chuàng)建
通過上面知識,我們已經(jīng)知道在numpy
中,數(shù)組是ndarray
類型的,接下來我們就看看學(xué)習(xí)如何利用numpy
來創(chuàng)建各種數(shù)組。
1.利用構(gòu)造函數(shù)array()
創(chuàng)建
利用構(gòu)造函數(shù)array()
創(chuàng)建一維或多維數(shù)組,其參數(shù)是類似于數(shù)組的對象,如列表等。當(dāng)然,也可以在創(chuàng)建的時候傳入數(shù)據(jù)類型,通過dtype=
指定,取值:
int系列包括np.int64
(默認(rèn))、np.int16
、np.int32
、np.int128
;
float系列包括:np.float64
(默認(rèn))、np.float16
、np.float32
、np.float84
、np.float96
、np.float128
、np.float256
等,示例如下:
import numpy as np
# 構(gòu)造函數(shù)構(gòu)建
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 創(chuàng)建的同時指定數(shù)據(jù)類型為float64
arr2 = np.array([[11, 22, 33],
[44, 55, 66]], dtype=np.float64)
print(arr1)
print(arr2)
運行結(jié)果:
[[1 2 3]
[4 5 6]]
[[11. 22. 33.]
[44. 55. 66.]]
2.利用arrange()
創(chuàng)建
numpy
中arrange()
的用法和Python
中range()
一樣,我們可以直接傳入一個size,也可以指定起始值-結(jié)束值-步長,numpy
中arrange()
還可以重新定義reshape(shape)
,如下面例子2.3中:np.arange(12).reshape((3, 4))
。示例如下:
import numpy as np
# 2.1利用arrange()來創(chuàng)建
arr3 = np.arange(12)
print(arr3)
print("-" * 20)
# 2.2利用arrange()來創(chuàng)建,
arr4 = np.arange(10, 21)
print(arr4)
print("+" * 20)
# 2.3利用arrange()來創(chuàng)建,重新定義shape
arr5 = np.arange(12).reshape((3, 4))
print(arr5)
運行結(jié)果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]
--------------------
[10 11 12 13 14 15 16 17 18 19 20]
++++++++++++++++++++
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
3.生產(chǎn)隨機數(shù)來創(chuàng)建
利用np.random.random(12)
會生產(chǎn)一系列從0-1
之間的符合標(biāo)準(zhǔn)正態(tài)分布隨機數(shù)組成的數(shù)組。我們指定隨機數(shù)的個數(shù),即要得到的數(shù)組長度,還可以在創(chuàng)建的同時重新定義shape:np.random.random((3, 4))
。示例如下,要注意觀察不同:
import numpy as np
# 3.1 利用隨機數(shù)創(chuàng)建數(shù)組
random_arr4 = np.random.random(12)
print(random_arr4)
print("-" * 20)
# 3.2 利用隨機數(shù)創(chuàng)建數(shù)組, 并指定shape
random_arr5 = np.random.random((3, 4))
print(random_arr5)
運行結(jié)果:
[0.47430035 0.27107492 0.786811 0.4158894 0.09536015 0.87473283 0.10045984 0.70662808 0.15931372 0.96116861 0.45779735 0.18718144]
--------------------
[[0.4010681 0.0760198 0.03891688 0.80331814]
[0.33589807 0.43356063 0.79576128 0.74174092]
[0.31945365 0.21740648 0.68029056 0.32781636]]
4.利用linspace()
線性等分來創(chuàng)建
numpy
中linspace(start, end, total_count)
線性等分來創(chuàng)建數(shù)組時,需要傳入起始值、結(jié)束值、將這段數(shù)等分為total_count
份。
這種創(chuàng)建方式特別適用于:知道起始值、結(jié)束值和總個數(shù)的情況。常用來設(shè)置自變量的取值,例如:x = np.linspace(-10, 10, 100)
,將會得到(-10, 10)
等分100份后的數(shù)據(jù)組成的數(shù)組。
import numpy as np
# 4 利用線性等分,創(chuàng)建數(shù)組
x = np.linspace(-10, 10, 50)
print(x)
運行結(jié)果:
[-10. -9.59183673 -9.18367347 -8.7755102 -8.36734694
-7.95918367 -7.55102041 -7.14285714 -6.73469388 -6.32653061
-5.91836735 -5.51020408 -5.10204082 -4.69387755 -4.28571429
-3.87755102 -3.46938776 -3.06122449 -2.65306122 -2.24489796
-1.83673469 -1.42857143 -1.02040816 -0.6122449 -0.20408163
0.20408163 0.6122449 1.02040816 1.42857143 1.83673469
2.24489796 2.65306122 3.06122449 3.46938776 3.87755102
4.28571429 4.69387755 5.10204082 5.51020408 5.91836735
6.32653061 6.73469388 7.14285714 7.55102041 7.95918367
8.36734694 8.7755102 9.18367347 9.59183673 10. ]
5.全為0的數(shù)組np.zeros(shape)
numpy
提供了可以直接創(chuàng)建所有元素為0的數(shù)組,方式為:np.zeros(shape)
。
官網(wǎng)的解釋:The function zeros creates an array full of zeros
,示例如下:
import numpy as np
# 5 全為0的數(shù)組
arr5 = np.zeros((3, 4))
print(arr5)
運行結(jié)果:
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
6.全為1的數(shù)組np.ones(shape)
numpy
提供了可以直接創(chuàng)建所有元素為1的數(shù)組,方式為:np.ones(shape)
。
官網(wǎng)的解釋:the function ones creates an array full of ones
,示例如下:
import numpy as np
# 6 全為1的數(shù)組
arr6 = np.ones((2, 3, 4))
print(arr6)
運行結(jié)果:
[[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]]
7.空元素數(shù)組
numpy
提供了可以直接創(chuàng)建所有元素為1的數(shù)組,方式為:np.empty(shape)
,要注意的是它的元素的初始值是隨機的,這取決于這塊內(nèi)存中的值。
官網(wǎng)的解釋:the function empty creates an array whose initial content is random and depends on the state of the memory. By default, the dtype of the created array is float64
,示例如下:
import numpy as np
# 創(chuàng)建空元素數(shù)組
arr7 = np.empty((3, 4))
print(arr7)
數(shù)組的常見操作
1.基本運算
- 加、減、乘、除
(+、-、*、/)
對兩個數(shù)組做加(減、乘、除)法運算,是對應(yīng)位置的元素分別做加(減、乘、除)法運算。
示例如下:
import numpy as np
arr1 = np.array([[11, 12, 13],
[14, 15, 16]])
arr2 = np.array([[1, 2, 3],
[4, 5, 6]])
print("arr1:")
print(arr1)
print("arr2:")
print(arr2)
print("arr1 + arr2 = ")
print(arr1 + arr2)
print("arr1 - arr2 = ")
print(arr1 - arr2)
print("arr2 * arr1 = ")
print(arr2 * arr1)
print("arr1 / arr2 = ")
print(arr1 / arr2)
運行結(jié)果:
arr1:
[[11 12 13]
[14 15 16]]
arr2:
[[1 2 3]
[4 5 6]]
arr1 + arr2 =
[[12 14 16]
[18 20 22]]
arr1 - arr2 =
[[10 10 10]
[10 10 10]]
arr2 * arr1 =
[[11 24 39]
[56 75 96]]
arr1 / arr2 =
[[11. 6. 4.33333333]
[ 3.5 3. 2.66666667]]
說明:對兩個數(shù)組做加(減、乘、除)法運算,是對應(yīng)位置的元素分別做加(減、乘、除)法運算。正因為如此規(guī)則,所以要求參與運算的兩個數(shù)組為同形數(shù)組,也就是要求shape
必須一樣,否則會報錯ValueError: operands could not be broadcast together with shapes
。
下面例子中,保持arr1
的shape
為(2, 3)
不變;利用reshape()
修改arr2
的shape
為(6,)
,此時再進(jìn)行加法運算操作:
import numpy as np
arr1 = np.array([[11, 12, 13],
[14, 15, 16]])
arr2 = np.array([[1, 2, 3],
[4, 5, 6]]).reshape((6,))
print("arr1:")
print(arr1)
print("arr2:")
print(arr2)
print("arr1 + arr2 = ")
print(arr1 + arr2)
運算結(jié)果:
Traceback (most recent call last):
File "D:/TensorFlowProjects/np_numpy/numpy_jianshu.py", line 15, in <module>
print(arr1 + arr2)
ValueError: operands could not be broadcast together with shapes (2,3) (6,)
- 多次方
(**)
在numpy中,多次方運算同樣作用于數(shù)組中每個元素。運算符號為**
,運算符**
后面是幾就做幾次運算。同樣要求參與運算的兩個數(shù)組為同形數(shù)組,也就是要求shape
必須一樣,否則會報錯ValueError: operands could not be broadcast together with shapes
。
例如:arr1 ** 2
表示對數(shù)組arr1
中每個元素做平方運算。
再如:arr1 ** 3
表示對數(shù)組arr1
中每個元素做3次方運算。
import numpy as np
arr1 = np.arange(6).reshape((2, 3))
print("arr1: ")
print(arr1)
print("-" * 20)
# 2次方運算
print(arr1 ** 2)
print("-" * 20)
# 3次方運算
print(arr1 ** 3)
運算結(jié)果:
arr1:
[[0 1 2]
[3 4 5]]
--------------------
[[ 0 1 4]
[ 9 16 25]]
--------------------
[[ 0 1 8]
[ 27 64 125]]
- 矩陣乘
矩陣乘是用np
提供的dot
,形如:np.dot(arr1, arr2)
或arr1.dot(arr2)
。需要注意的是,參與運算的兩個數(shù)組要符合矩陣乘的乘法要求:前一個矩陣的列必須等于后一個矩陣的行。如果不滿足此,則會運行報錯。
下面例子,3行4列
x 4行2列
,計算后將會得到3行2列
的矩陣。
import numpy as np
arr1 = np.arange(12).reshape((3, 4))
arr2 = np.arange(8).reshape((4, 2))
print("arr1 = ")
print(arr1)
print("arr2 = ")
print(arr2)
print("-" * 20)
print(np.dot(arr1, arr2))
print("+" * 20)
print(arr1.dot(arr2))
運算結(jié)果:
arr1 =
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
arr2 =
[[0 1]
[2 3]
[4 5]
[6 7]]
--------------------
[[ 28 34]
[ 76 98]
[124 162]]
++++++++++++++++++++
[[ 28 34]
[ 76 98]
[124 162]]
提示:
如果你在運算過程中遇到ValueError: shapes (3,4) and (3,2) not aligned: 4 (dim 1) != 3 (dim 0)
,則說明參與運算的兩個矩陣不符合矩陣乘的運算規(guī)則:前一個矩陣的列必須等于后一個矩陣的行。
- 和數(shù)值比較
和數(shù)值比較,形如arr1 > 3
,會把數(shù)組中每個元素和該數(shù)值3
進(jìn)行比較,滿足則為True
,不滿足則為False
,最后會得到一個由True、False
組成的數(shù)組。
import numpy as np
arr1 = np.array([[0, 2, 4],
[1, 3, 5]])
print(arr1 > 3)
運算結(jié)果:
[[0 2 4]
[1 3 5]]
[[False False True]
[False False True]]
- 求和
numpy中求和提供了sum
,可以計算一個數(shù)組中所有元素的和np.sum(arr)
,也可以指定計算某個軸上的和np.sum(arr,axis=0或1或2等)
。
如果是2維數(shù)組,axis=0
表示計算列上的和;axis=1
表示計算行上的和;
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
# 計算所有元素的和
print(np.sum(arr_2d))
print("-" * 20)
# 計算指定軸上的元素的和
print(np.sum(arr_2d, axis=0))
print("-" * 20)
print(np.sum(arr_2d, axis=1))
運行結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
66
--------------------
[12 15 18 21]
--------------------
[ 6 22 38]
如果是3維數(shù)組,形如shape 為 (2, 3, 4)的
,此時axis=0表示計算shape
為(3, 4)
數(shù)組求和,計算后會得到一個(3, 4)
數(shù)組。;axis=1表示計算列上的和,計算后會得到一個(2, 4)
數(shù)組;axis=2表示計算行上的和,計算后會得到一個(2, 3)
數(shù)組;
import numpy as np
arr_3d = np.arange(24).reshape((2, 3, 4))
print(arr_3d)
# 計算所有元素的和
print("所有元素的和:{}".format(np.sum(arr_3d)))
# 計算指定軸上的元素的和
print("axis=0,shape=(2, 3, 4),會得到(3, 4)的數(shù)組:")
print(np.sum(arr_3d, axis=0))
print("axis=1,shape=(2, 3, 4),會得到(2, 4)的數(shù)組:")
print(np.sum(arr_3d, axis=1))
print("axis=2,shape=(2, 3, 4),會得到(2, 3)的數(shù)組:")
print(np.sum(arr_3d, axis=2))
運行結(jié)果:
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
所有元素的和:276
axis=0,shape=(2, 3, 4),會得到(3, 4)的數(shù)組:
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
axis=1,shape=(2, 3, 4),會得到(2, 4)的數(shù)組:
[[12 15 18 21]
[48 51 54 57]]
axis=2,shape=(2, 3, 4),會得到(2, 3)的數(shù)組:
[[ 6 22 38]
[54 70 86]]
如果是更高維數(shù)組,則依次類推。關(guān)鍵是區(qū)分軸序號代表的是什么。
- 求最大值
numpy中求最大值提供了max
,可以計算一個數(shù)組中所有元素中最大的元素np.max(arr)
,也可以指定計算某個軸上的最大的元素np.max(arr,axis=0或1或2等)
。
求最大值所在的索引,np.argmax(arr,axis=0或1或2等)
import numpy as np
arr_2d = np.array([[2, 4, 6],
[1, 3, 5]])
print(arr_2d)
# 數(shù)組中最大元素
print("數(shù)組中最大元素{}".format(np.max(arr_2d)))
print("數(shù)組中最大元素索引{}".format(np.argmax(arr_2d)))
# 2維的軸axis=0上的最大值,也即列上的最大值
print("列上的最大值{}".format(np.max(arr_2d, axis=0)))
運行結(jié)果:
[[2 4 6]
[1 3 5]]
數(shù)組中最大元素:6
數(shù)組中最大元素索引:2
列上的最大值:[2 4 6]
- 求最小值
numpy中求最小值提供了min
,可以計算一個數(shù)組中所有元素最小元素值np.min(arr)
,也可以指定計算某個軸上的最小元素值np.min(arr,axis=0或1或2等)
。
求最小值所在的索引,np.argmin(arr,axis=0或1或2等)
import numpy as np
arr_2d = np.array([[2, 4, 6],
[1, 3, 5]])
print(arr_2d)
# 數(shù)組中最小元素
print("數(shù)組中最小元素:{}".format(np.min(arr_2d)))
print("數(shù)組中最小元素索引:{}".format(np.argmin(arr_2d)))
# 2維的軸axis=0上的最小值,也即列上的最小值
print("列上的最小值:{}".format(np.min(arr_2d, axis=0)))
運行結(jié)果:
[[2 4 6]
[1 3 5]]
數(shù)組中最小元素:1
數(shù)組中最小元素索引:3
列上的最小值:[1 3 5]
- 求平均數(shù)、中位數(shù)、加權(quán)平均數(shù)
numpy中求平均數(shù)、中位數(shù)、加權(quán)平均數(shù),分別提供了mean(arr)
、media(arr)
、average(arr)
,也可以指定計算某個軸上的平均數(shù)、中位數(shù)、加權(quán)平均數(shù)。
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
# 權(quán)重,加權(quán)平均數(shù)時用到了
weights = np.array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 2]])
print(arr_2d)
print(weights)
print("平均數(shù){}".format(np.mean(arr_2d)))
print("中位數(shù){}".format(np.median(arr_2d)))
print("加權(quán)平均數(shù){}".format(np.average(arr_2d, weights=weights)))
運算結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[1 1 1 1]
[1 1 1 1]
[1 1 1 2]]
平均數(shù)5.5
中位數(shù)5.5
加權(quán)平均數(shù)5.923076923076923
- 累和
numpy中求累和提供了cumsum
,可以計算一個數(shù)組中求累和np.cumsum(arr)
,也可以指定計算某個軸上求累和np.cumsum(arr,axis=0或1或2等)
。
import numpy as np
arr1 = np.arange(6)
print(arr1)
# 求累和
print(np.cumsum(arr1))
運算結(jié)果:
[0 1 2 3 4 5]
[ 0 1 3 6 10 15]
累和計算規(guī)則如圖:
- 累差
numpy中求累和提供了diff
,可以計算一個數(shù)組中求累和np.diff(arr)
,也可以指定計算某個軸上求累和np.diff(arr,axis=0或1或2等)
。
import numpy as np
arr1 = np.array([1, 3, 5, 2, 4, 6])
print(arr1)
# 求累差
print(np.diff(arr1))
運行結(jié)果:
[1 3 5 2 4 6]
[ 2 2 -3 2 2]
- 非零元素
numpy中找一個數(shù)組中非零元素提供了np.nonzero(arr)
,示例如下:
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
print(np.nonzero(arr_2d))
運行結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64),
array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))
解析:調(diào)用非零元素方法得到了(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64), array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))
,由于原數(shù)組是2維的,所以打印結(jié)果中這個包含兩個數(shù)組,分別表示:非零元素所在的行的索引組成的數(shù)組,非零元素所在的列的索引組成的數(shù)組。
可以看到除了(0,0)
處的元素外,其余都非零,所以有上面的打印結(jié)果。
- 排序
numpy中排序提供了sort
,可以指定某個軸上元素排序np.sort(arr,axis=0或1或2等)
,也可以指定排序使用的方法,kind
數(shù)組排序時使用的方法。
a :所需排序的數(shù)組
axis:數(shù)組排序時的基準(zhǔn),axis=0,按行排列;axis=1,按列排列
kind:數(shù)組排序時使用的方法,其中: kind= ′ quicksort ′ 為快排;kind= ′ mergesort ′ 為混排;kind= ′ heapsort ′ 為堆排;
order:一個字符串或列表,可以設(shè)置按照某個屬性進(jìn)行排序。
import numpy as np
arr1 = np.array([[1, 13, 5, 12, 4, 6],
[10, 11, 12, 7, 8, 9]])
print(arr1)
print("-" * 20)
print(np.sort(arr1))
print("-" * 20)
# axis=0 對每一列中的元素排序
print(np.sort(arr1, axis=0, kind="quicksort"))
print("-" * 20)
# axis=1 對每一行中的元素排序
print(np.sort(arr1, axis=1))
運行結(jié)果:
[[ 1 13 5 12 4 6]
[10 11 12 7 8 9]]
--------------------
[[ 1 4 5 6 12 13]
[ 7 8 9 10 11 12]]
--------------------
[[ 1 11 5 7 4 6]
[10 13 12 12 8 9]]
--------------------
[[ 1 4 5 6 12 13]
[ 7 8 9 10 11 12]]
- 矩陣的轉(zhuǎn)置
numpy對矩陣的轉(zhuǎn)置提供了多種實現(xiàn)方式,最常用的arr.T
和np.transpose(arr)
。需要注意的是,numpy提供了迭代行,并沒有提供直接迭代列。若要迭代列,一般都是先轉(zhuǎn)置一下再迭代行就行了。
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
print("-" * 20)
# 矩陣的轉(zhuǎn)置,方式1
print(arr_2d.T)
print("-" * 20)
# 矩陣的轉(zhuǎn)置,方式2
print(np.transpose(arr_2d))
運行結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
--------------------
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
--------------------
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
- 數(shù)據(jù)裁剪處理
numpy對數(shù)組中的元素提供了裁剪處理的方法np.clip(arr, min, max)
, 對該函數(shù)的理解:小于最小值得按最小值處理;大于最大值的按最大值處理,處于最小值和最大值之間的保留原數(shù)據(jù)。示例如下:
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
# 數(shù)據(jù)的裁剪
print(np.clip(arr_2d, 5, 8))
運行結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[5 5 5 5]
[5 5 6 7]
[8 8 8 8]]
- 展開鋪平
numpy對數(shù)組中可以重新定義shape
, 方法是reshape(shape)
,也提供了降維處理,直接展開鋪平為一維arr.flatten()
。示例如下:
import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
# 展開鋪平操作
print(arr_2d.flatten())
運行結(jié)果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[ 0 1 2 3 4 5 6 7 8 9 10 11]
2.array合并
數(shù)組的合并,分為在垂直方向合并np.vstack((arr1, arr2))
和在水平方向合并np.hstack((arr1, arr2))
。
import numpy as np
arr1 = np.array([1, 1, 1])
arr2 = np.array([2, 2, 2])
print(arr1)
print("-" * 10)
print(arr2)
print("在列方向合并:")
print(np.vstack((arr1, arr2)))
print("在行方向合并:")
print(np.hstack((arr1, arr2)))
運行結(jié)果:
[1 1 1]
----------
[2 2 2]
在列方向合并:
[[1 1 1]
[2 2 2]]
在行方向合并:
[1 1 1 2 2 2]
當(dāng)然,也可以使用np.concatenate((arr1, arr2), axis=0或1或2等)
:
import numpy as np
arr1 = np.array([[1, 2],
[3, 4]])
arr2 = np.array([[5, 6]])
print(arr1)
print("-" * 10)
print(arr2)
print("在垂直方向合并:")
print(np.concatenate((arr1, arr2), axis=0))
print("在水平方向合并:")
print(np.concatenate((arr1, arr2.T), axis=1))
運行結(jié)果:
[[1 2]
[3 4]]
----------
[[5 6]]
在列方向合并:
[[1 2]
[3 4]
[5 6]]
在行方向合并:
[[1 2 5]
[3 4 6]]
3.array分割
數(shù)組的拆分,分為在垂直方向拆分np.vsplit(arr1, 幾等分)
和在水平方向拆分np.hsplit(arr1, 幾等分)
。
import numpy as np
arr_2d = np.arange(24).reshape((4, 6))
print(arr_2d)
# 在垂直方向上等分2份
print(np.vsplit(arr_2d, 2))
# 在水平方向上等分2份
print(np.hsplit(arr_2d, 2))
運行結(jié)果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]),
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])]
[array([[ 0, 1, 2],
[ 6, 7, 8],
[12, 13, 14],
[18, 19, 20]]),
array([[ 3, 4, 5],
[ 9, 10, 11],
[15, 16, 17],
[21, 22, 23]])]
當(dāng)然,也可以使用np.split(arr1, axis=0或1或2等)
:
import numpy as np
arr_2d = np.arange(24).reshape((4, 6))
print(arr_2d)
# 在垂直方向上等分2份
print(np.split(arr_2d, 2, axis=0))
# 在水平方向上等分3份
print(np.split(arr_2d, 3, axis=1))
運行結(jié)果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]),
array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])]
[array([[ 0, 1],
[ 6, 7],
[12, 13],
[18, 19]]),
array([[ 2, 3],
[ 8, 9],
[14, 15],
[20, 21]]),
array([[ 4, 5],
[10, 11],
[16, 17],
[22, 23]])]
4.array的copy
numpy中數(shù)組的賦值操作,默認(rèn)是不進(jìn)行拷貝的。下面例子中,arr1 和arr2指向了內(nèi)存中的同一內(nèi)存地址,是不同變量指向了同一對象。
import numpy as np
# 創(chuàng)建數(shù)組arr1
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 把數(shù)組arr1賦值給數(shù)組arr2,
arr2 = arr1
print(arr1)
print(arr2)
# arr1和arr2是否同一對象
print(arr1 is arr2)
運行結(jié)果:
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
True
通過一個變量修改數(shù)組的值,由于兩個數(shù)組變量指向同一對象,所以另一處的值也是被修改后的:
# 上接
arr1[1][1] = 15
print(arr1)
print(arr2)
運行結(jié)果:
[[ 1 2 3]
[ 4 15 6]]
[[ 1 2 3]
[ 4 15 6]]
上面例子中,之前一處兩個變量指向的同一數(shù)組,數(shù)據(jù)發(fā)生了變化。是因為arr2 = arr1
這句賦值操作默認(rèn)采用的不拷貝。,如果,我想讓arr1和arr2是獨立的存在,當(dāng)一處修改,另一處數(shù)據(jù)不變動。那么只需要賦值時采用copy
復(fù)制一份即可。代碼如下:
import numpy as np
# 創(chuàng)建數(shù)組arr1
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 把數(shù)組arr1賦值給數(shù)組arr2,
arr2 = arr1.copy()
print(arr1)
print(arr2)
# arr1和arr2是否同一對象
print("arr1和arr2是否同一對象:{}".format(arr1 is arr2))
# 修改arr1[1][1]的元素的值為15
arr1[1][1] = 15
print(arr1)
print(arr2)
運行結(jié)果:
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
arr1和arr2是否同一對象:False
[[ 1 2 3]
[ 4 15 6]]
[[1 2 3]
[4 5 6]]
說明:arr2 = arr1.copy()
復(fù)制后,arr2
和 arr1
就相互獨立,一個數(shù)據(jù)修改不再影響另一個數(shù)組中的數(shù)據(jù)了。
索引操作
numpy中數(shù)組是矩陣的基礎(chǔ),兩種可以相互轉(zhuǎn)化。數(shù)組操作中,索引的處理決定了操作哪些元素,因此索引操作變得至關(guān)重要。
一維數(shù)組,形如arr1=[0, 1, 2, 3, 4]
,arr1[1]
拿到的是元素1
;
一維數(shù)組,形如
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
此時arr1[1]
拿到的是第1整行:[ 5 6 7 8 9]
;
arr1[1][1]
拿到的是元素6
;
arr1[:, 1]
拿到的是第1整列:[ 1 6 11]
;
arr1[1, 1:3]
拿到的是第1行第1~3列的元素:[ 6 7]
;
方差、標(biāo)準(zhǔn)差
numpy提供了計算方差、標(biāo)準(zhǔn)差的函數(shù),在統(tǒng)計計算時非常有用:
計算數(shù)組的極差:np.pth(a)=max(a)-min(a)
計算方差(總體方差):np.var(a)
標(biāo)準(zhǔn)差:np.std(a)
import numpy as np
arr = np.arange(15).reshape((3, 5))
print(arr)
# 方差
print(np.var(arr))
# 標(biāo)準(zhǔn)差
print(np.std(arr))
運行結(jié)果:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
18.666666666666668
4.320493798938574
多項式
多項式擬合:poly= np.polyfit(x,a,n)
,擬合點集a
得到n
級多項式,其中x
為橫軸長度,返回多項式的系數(shù)
多項式求導(dǎo)函數(shù):np.polyder(poly)
,返回導(dǎo)函數(shù)的系數(shù)
得到多項式的n階導(dǎo)函數(shù):多項式.deriv(m = n)
多項式求根:np.roots(poly)
多項式在某點上的值:np.polyval(poly,x[n])
,返回poly
多項式在橫軸點上x[n]
上的值
兩個多項式做差運算: np.polysub(a,b)
線性代數(shù)基礎(chǔ)運算
估計線性模型中的系數(shù):a=np.linalg.lstsq(x,b),有b=a*x
求方陣的逆矩陣:np.linalg.inv(A)
求廣義逆矩陣:np.linalg.pinv(A)
求矩陣的行列式:np.linalg.det(A)
解形如AX=b的線性方程組:np.linalg.solve(A,b)
求矩陣的特征值:np.linalg.eigvals(A)
求特征值和特征向量:np.linalg.eig(A)
Svd分解:np.linalg.svd(A)
概率分布
產(chǎn)生二項分布的隨機數(shù):np.random.binomial(n,p,size=…)
,其中n,p,size
分別是每輪試驗次數(shù)、概率、輪數(shù)
產(chǎn)生超幾何分布隨機數(shù):np.random.hypergeometric(n1,n2,n,size=…)
,其中參數(shù)意義分別是物件1總量、物件2總量、每次采樣數(shù)、試驗次數(shù)
產(chǎn)生N個正態(tài)分布的隨機數(shù):np.random.normal(均值,標(biāo)準(zhǔn)差,N)
產(chǎn)生N個對數(shù)正態(tài)分布的隨機數(shù):np.random.lognormal(mean,sigma,N)
小結(jié)
本文學(xué)習(xí)了numpy的常用用法,具體包括:如何安裝及導(dǎo)入numpy、數(shù)組的重要屬性、數(shù)組的多種創(chuàng)建方式、數(shù)組的常見操作、數(shù)組的合并、拆分;索引操作、多項式、方差、標(biāo)準(zhǔn)差、概率分布等知識。這一節(jié)知識是后面學(xué)習(xí)Pandas
和TensorFlow
的基礎(chǔ),務(wù)必掌握。
參考資料:NumPy官網(wǎng)教程(英文)