python編程必學模塊,NumPy全網獨家詳解!

python編程必學模塊,NumPy全網獨家詳解!

前言(私信小編007自動獲取大量Python視頻教程以及各類PDF!)

numpy是支持 Python語言的數值計算擴充庫,其擁有強大的高維度數組處理與矩陣運算能力。除此之外,numpy還內建了大量的函數,方便你快速構建數學模型。

安裝及導入numpy

安裝numpy:

pip install numpy

導入numpy,推薦做法是:

import numpy as np

當然,如果你不想像上面導入,你也可以和其他模塊導入方式一樣直接import numpy,但還是推薦用import numpy as np這種方式,後面用到numpy的地方都可以用別名np了,更加簡潔。

numpy數學中的計算

學習完後,可以熟練掌握數組各種方式的創建、屬性及數組操作;對矩陣的常見操作、也可以對多項式求導、作圖等。

1.求矩陣A的秩

提示:在線性代數中,一個矩陣A的列秩是A的線性獨立的縱列的極大數目。類似地,行秩是A的線性無關的橫行的極大數目。通俗一點說,如果把矩陣看成一個個行向量或者列向量,秩就是這些行向量或者列向量的秩,也就是極大無關組中所含向量的個數。


python編程必學模塊,NumPy全網獨家詳解!


矩陣A


解析:在numpy中,求矩陣的秩用nf.linalg.matrix_rank(array)

2.求矩陣A的轉置矩陣

轉置矩陣:將矩陣的行列互換得到的新矩陣稱為轉置矩陣,轉置矩陣的行列式不變。

解析:在numpy中,求矩陣A的轉置矩陣用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的轉置矩陣:")
print(A.T)

運行結果:

矩陣A:
[[ 3 2 0 5 0]
[ 3 -2 3 6 -1]
[ 2 0 1 5 -3]
[ 1 6 -4 -1 4]]

A的秩為:3A的轉置矩陣:[[ 3 3 2 1]
[ 2 -2 0 6]
[ 0 3 1 -4]
[ 5 6 5 -1]
[ 0 -1 -3 4]]

手動求解:

python編程必學模塊,NumPy全網獨家詳解!



手動求解矩陣A的秩


3.求矩陣A的逆矩陣

說明:逆矩陣是對方陣定義的,因此逆矩陣一定是方陣。

逆矩陣:設A是數域上的一個n階矩陣,若在相同數域上存在另一個n階矩陣B,使得: AB=BA=E ,則我們稱B是A的逆矩陣,而A則被稱為可逆矩陣。注:E為單位矩陣。


python編程必學模塊,NumPy全網獨家詳解!


矩陣A

解析:在numpy中,求矩陣A的轉置矩陣用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)

運行結果:

矩陣A:
[[ 0 1 2]
[ 1 1 4]
[ 2 -1 0]]
A的逆矩陣:
[[ 2. -1. 1. ]
[ 4. -2. 1. ]
[-1.5 1. -0.5]]

手動計算:

python編程必學模塊,NumPy全網獨家詳解!


手動計算求矩陣A的逆矩陣


4.求y = -2x^2 + 4x + 16的根,並求出其導函數

python編程必學模塊,NumPy全網獨家詳解!


多項式 -2x^2 + 4x + 16的圖像


解析:為了形象展示多項式,我們借用matplotlib順便繪製了該函數的圖像。後面會專門學習如何繪製,此處大概瞭解一下matplotlib即可。numpy中的多項式:np.poly1d(arr),需要把參數傳入。本例子中放在了一個數組中arr = np.array([-2, 4, 16])傳入的。對多項式求導,想要求幾階導數,只需要這裡實參m傳入數字幾即可。func.deriv(m=1);定製定義域np.linspace(-4, 6, 100),這樣把-6--6之間進行100等分,利用這些數據創建了一個長度為100的數組。

import numpy as npimport matplotlib.pyplot as plt
# y = -2x^2 + 4x + 16
arr = np.array([-2, 4, 16])
func = np.poly1d(arr)
# m=1表示求一階導數,依次類推
func1 = func.deriv(m=1)
# 設置定義域-4,6;並將定義域等分了100份
x = np.linspace(-4, 6, 100)
y = func(x)
y1 = func1(x)
# 打印多項式
print(func)
# 打印多項式對應的一階導數
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()

運行結果:

python編程必學模塊,NumPy全網獨家詳解!


多項式求根及一階導數

數組的重要屬性

numpy的主要操作對象是同類的多維數組,即一個由相同類型元素(通常是數字)組成的、以正數為索引的數據表。在numpy裡面,維度稱為“軸”。

舉例來說,三維空間內一點的座標[1,2,1]有一個軸,三個元素,所以我們通常稱它的長度為3。在以下所示的例子中,數組有兩個軸,第一個軸的長度為2,第二個軸的長度為3。

[[ 1., 0., 0.],
[ 0., 1., 2.]]

numpy的數組類型叫做ndarray,也就是numpy數組(以下簡稱為數組)。需要注意的是,numpy.array不同於Python標準庫中的array.array,後者只處理一維的數組並且提供了很少的功能。一個ndarray對象有以下一些重要的屬性:

  • ndarray.ndim

數組的軸的數量,即維度數量。

  • ndarray.shape

數組的維度。返回的是一個整數元組,指示了一個數組在各個維度的大小。對於一個n行m列的矩陣來說,它的shape是(n,m)。shape的元組長度因此是軸的數量,即ndim。

  • ndarray.size

數組所有元素的數量,等於shape返回元組元素的乘積。

  • ndarray.dtype

一個用於描述數組元素類型的對象。可以用標準Python類型來創造或指定dtype的類型。另外,Numpy也提供了自己的類型,如numpy.int32,numpy.int16,numpy.float64等。

  • ndarray.itemsize

數組每個元素的字節大小。比如一個數組的元素為float64,它的itemsize為8(=64/8),

complex32的itemsize為4(=32/8)。這個屬性等同於ndarray.dtype.itemsize。

  • ndarray.data

包含了數組每個實際元素的緩衝器。一般來說我們不會用到這個屬性因為我們可以通過索引工具來獲取到數組的每個元素的值。

數組的創建

通過上面知識,我們已經知道在numpy中,數組是ndarray類型的,接下來我們就看看學習如何利用numpy來創建各種數組。

1.利用構造函數array()創建

利用構造函數array()創建一維或多維數組,其參數是類似於數組的對象,如列表等。當然,也可以在創建的時候傳入數據類型,通過dtype=指定,取值:

int系列包括np.int64(默認)、np.int16、np.int32、np.int128;

float系列包括:np.float64(默認)、np.float16、np.float32、np.float84、np.float96、np.float128、np.float256等,示例如下:

import numpy as np
# 構造函數構建
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 創建的同時指定數據類型為float64
arr2 = np.array([[11, 22, 33],
[44, 55, 66]], dtype=np.float64)
print(arr1)
print(arr2)

運行結果:

[[1 2 3]
[4 5 6]]
[[11. 22. 33.]
[44. 55. 66.]]

2.利用arrange()創建

numpy中arrange()的用法和Python中range()一樣,我們可以直接傳入一個size,也可以指定起始值-結束值-步長,numpy中arrange()還可以重新定義reshape(shape),如下面例子2.3中:np.arange(12).reshape((3, 4))。示例如下:

import numpy as np 

# 2.1利用arrange()來創建
arr3 = np.arange(12)
print(arr3)
print("-" * 20)
# 2.2利用arrange()來創建,
arr4 = np.arange(10, 21)
print(arr4)
print("+" * 20)
# 2.3利用arrange()來創建,重新定義shape
arr5 = np.arange(12).reshape((3, 4))
print(arr5)

運行結果:

[ 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.生產隨機數來創建

利用np.random.random(12)會生產一系列從0-1之間的符合標準正態分佈隨機數組成的數組。我們指定隨機數的個數,即要得到的數組長度,還可以在創建的同時重新定義shape:np.random.random((3, 4))。示例如下,要注意觀察不同:

import numpy as np
# 3.1 利用隨機數創建數組
random_arr4 = np.random.random(12)
print(random_arr4)
print("-" * 20)
# 3.2 利用隨機數創建數組, 並指定shape
random_arr5 = np.random.random((3, 4))

print(random_arr5)

運行結果:

[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()線性等分來創建

numpy中linspace(start, end, total_count)線性等分來創建數組時,需要傳入起始值、結束值、將這段數等分為total_count份。

這種創建方式特別適用於:知道起始值、結束值和總個數的情況。常用來設置自變量的取值,例如:x = np.linspace(-10, 10, 100),將會得到(-10, 10)等分100份後的數據組成的數組。

import numpy as np
# 4 利用線性等分,創建數組
x = np.linspace(-10, 10, 50)
print(x)

運行結果:

[-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的數組np.zeros(shape)

numpy提供了可以直接創建所有元素為0的數組,方式為:np.zeros(shape)。

官網的解釋:The function zeros creates an array full of zeros,示例如下:

import numpy as np
# 5 全為0的數組
arr5 = np.zeros((3, 4))
print(arr5)

運行結果:

[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]

6.全為1的數組np.ones(shape)

numpy提供了可以直接創建所有元素為1的數組,方式為:np.ones(shape)。

官網的解釋:the function ones creates an array full of ones,示例如下:

import numpy as np
# 6 全為1的數組
arr6 = np.ones((2, 3, 4))
print(arr6)

運行結果:

[[[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.空元素數組

numpy提供了可以直接創建所有元素為1的數組,方式為:np.empty(shape),要注意的是它的元素的初始值是隨機的,這取決於這塊內存中的值。

官網的解釋: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
# 創建空元素數組
arr7 = np.empty((3, 4))
print(arr7)


python編程必學模塊,NumPy全網獨家詳解!


numpy中dtype類型


python編程必學模塊,NumPy全網獨家詳解!


numpy數組生成函數彙總表

數組的常見操作

1.基本運算

  • 加、減、乘、除(+、-、*、/)

對兩個數組做加(減、乘、除)法運算,是對應位置的元素分別做加(減、乘、除)法運算。

示例如下:

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)

運行結果:

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]]

說明:對兩個數組做加(減、乘、除)法運算,是對應位置的元素分別做加(減、乘、除)法運算。正因為如此規則,所以要求參與運算的兩個數組為同形數組,也就是要求shape必須一樣,否則會報錯ValueError: operands could not be broadcast together with shapes。

下面例子中,保持arr1的shape為(2, 3)不變;利用reshape()修改arr2的shape為(6,),此時再進行加法運算操作:

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)

運算結果:

Traceback (most recent call last):
File "D:/TensorFlowProjects/np_numpy/numpy_jianshu.py", line 15, in
print(arr1 + arr2)
ValueError: operands could not be broadcast together with shapes (2,3) (6,)
  • 多次方(**)

在numpy中,多次方運算同樣作用於數組中每個元素。運算符號為**,運算符**後面是幾就做幾次運算。同樣要求參與運算的兩個數組為同形數組,也就是要求shape必須一樣,否則會報錯ValueError: operands could not be broadcast together with shapes。

例如:arr1 ** 2表示對數組arr1中每個元素做平方運算。

再如:arr1 ** 3表示對數組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)

運算結果:

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)。需要注意的是,參與運算的兩個數組要符合矩陣乘的乘法要求:前一個矩陣的列必須等於後一個矩陣的行。如果不滿足此,則會運行報錯。

下面例子,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))

運算結果:

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),則說明參與運算的兩個矩陣不符合矩陣乘的運算規則:前一個矩陣的列必須等於後一個矩陣的行。

  • 和數值比較

和數值比較,形如arr1 > 3,會把數組中每個元素和該數值3進行比較,滿足則為True,不滿足則為False,最後會得到一個由True、False組成的數組。

import numpy as np
arr1 = np.array([[0, 2, 4],
[1, 3, 5]])
print(arr1 > 3)

運算結果:

[[0 2 4]
[1 3 5]]
[[False False True]
[False False True]]
  • 求和

numpy中求和提供了sum,可以計算一個數組中所有元素的和np.sum(arr),也可以指定計算某個軸上的和np.sum(arr,axis=0或1或2等)。

如果是2維數組,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))

運行結果:

[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
66
--------------------
[12 15 18 21]
--------------------
[ 6 22 38]

如果是3維數組,形如shape 為 (2, 3, 4)的,此時axis=0表示計算shape為(3, 4)數組求和,計算後會得到一個(3, 4)數組。;axis=1表示計算列上的和,計算後會得到一個(2, 4)數組;axis=2表示計算行上的和,計算後會得到一個(2, 3)數組;

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)的數組:")
print(np.sum(arr_3d, axis=0))
print("axis=1,shape=(2, 3, 4),會得到(2, 4)的數組:")
print(np.sum(arr_3d, axis=1))
print("axis=2,shape=(2, 3, 4),會得到(2, 3)的數組:")

print(np.sum(arr_3d, axis=2))

運行結果:

[[[ 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)的數組:
[[12 14 16 18]
[20 22 24 26]
[28 30 32 34]]
axis=1,shape=(2, 3, 4),會得到(2, 4)的數組:
[[12 15 18 21]
[48 51 54 57]]
axis=2,shape=(2, 3, 4),會得到(2, 3)的數組:
[[ 6 22 38]
[54 70 86]]

如果是更高維數組,則依次類推。關鍵是區分軸序號代表的是什麼。

  • 求最大值

numpy中求最大值提供了max,可以計算一個數組中所有元素中最大的元素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)
# 數組中最大元素
print("數組中最大元素{}".format(np.max(arr_2d)))
print("數組中最大元素索引{}".format(np.argmax(arr_2d)))
# 2維的軸axis=0上的最大值,也即列上的最大值
print("列上的最大值{}".format(np.max(arr_2d, axis=0)))

運行結果:

[[2 4 6]
[1 3 5]]
數組中最大元素:6
數組中最大元素索引:2
列上的最大值:[2 4 6]
  • 求最小值

numpy中求最小值提供了min,可以計算一個數組中所有元素最小元素值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)
# 數組中最小元素
print("數組中最小元素:{}".format(np.min(arr_2d)))
print("數組中最小元素索引:{}".format(np.argmin(arr_2d)))
# 2維的軸axis=0上的最小值,也即列上的最小值

print("列上的最小值:{}".format(np.min(arr_2d, axis=0)))

運行結果:

[[2 4 6]
[1 3 5]]
數組中最小元素:1
數組中最小元素索引:3
列上的最小值:[1 3 5]
  • 求平均數、中位數、加權平均數

numpy中求平均數、中位數、加權平均數,分別提供了mean(arr)、media(arr)、average(arr),也可以指定計算某個軸上的平均數、中位數、加權平均數。

import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
# 權重,加權平均數時用到了
weights = np.array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 2]])
print(arr_2d)
print(weights)
print("平均數{}".format(np.mean(arr_2d)))
print("中位數{}".format(np.median(arr_2d)))
print("加權平均數{}".format(np.average(arr_2d, weights=weights)))

運算結果:

[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[1 1 1 1]
[1 1 1 1]

[1 1 1 2]]
平均數5.5
中位數5.5
加權平均數5.923076923076923
  • 累和

numpy中求累和提供了cumsum,可以計算一個數組中求累和np.cumsum(arr),也可以指定計算某個軸上求累和np.cumsum(arr,axis=0或1或2等)。

import numpy as np
arr1 = np.arange(6)
print(arr1)
# 求累和
print(np.cumsum(arr1))

運算結果:

[0 1 2 3 4 5]
[ 0 1 3 6 10 15]

累和計算規則如圖:

python編程必學模塊,NumPy全網獨家詳解!


累和計算規則

  • 累差

numpy中求累和提供了diff,可以計算一個數組中求累和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))

運行結果:

[1 3 5 2 4 6]
[ 2 2 -3 2 2]


python編程必學模塊,NumPy全網獨家詳解!


累差

  • 非零元素

numpy中找一個數組中非零元素提供了np.nonzero(arr),示例如下:

import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
print(np.nonzero(arr_2d))

運行結果:

[[ 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))

解析:調用非零元素方法得到了(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)),由於原數組是2維的,所以打印結果中這個包含兩個數組,分別表示:非零元素所在的行的索引組成的數組,非零元素所在的列的索引組成的數組。

可以看到除了(0,0)處的元素外,其餘都非零,所以有上面的打印結果。

  • 排序

numpy中排序提供了sort,可以指定某個軸上元素排序np.sort(arr,axis=0或1或2等),也可以指定排序使用的方法,kind數組排序時使用的方法。

a :所需排序的數組axis:數組排序時的基準,axis=0,按行排列;axis=1,按列排列kind:數組排序時使用的方法,其中: kind= ′ quicksort ′ 為快排;kind= ′ mergesort ′ 為混排;kind= ′ heapsort ′ 為堆排;order:一個字符串或列表,可以設置按照某個屬性進行排序。
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))

運行結果:

[[ 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]]
  • 矩陣的轉置

numpy對矩陣的轉置提供了多種實現方式,最常用的arr.T和np.transpose(arr)。需要注意的是,numpy提供了迭代行,並沒有提供直接迭代列。若要迭代列,一般都是先轉置一下再迭代行就行了。

import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
print("-" * 20)
# 矩陣的轉置,方式1
print(arr_2d.T)
print("-" * 20)
# 矩陣的轉置,方式2
print(np.transpose(arr_2d))

運行結果:

[[ 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]]
  • 數據裁剪處理

numpy對數組中的元素提供了裁剪處理的方法np.clip(arr, min, max), 對該函數的理解:小於最小值得按最小值處理;大於最大值的按最大值處理,處於最小值和最大值之間的保留原數據。示例如下:

import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
# 數據的裁剪
print(np.clip(arr_2d, 5, 8))

運行結果:

[[ 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對數組中可以重新定義shape, 方法是reshape(shape),也提供了降維處理,直接展開鋪平為一維arr.flatten()。示例如下:

import numpy as np
arr_2d = np.arange(12).reshape((3, 4))
print(arr_2d)
# 展開鋪平操作
print(arr_2d.flatten())

運行結果:

[[ 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合併

數組的合併,分為在垂直方向合併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)))

運行結果:

[1 1 1]
----------
[2 2 2]
在列方向合併:
[[1 1 1]
[2 2 2]]
在行方向合併:
[1 1 1 2 2 2]

當然,也可以使用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))

運行結果:

[[1 2]
[3 4]]

----------
[[5 6]]
在列方向合併:
[[1 2]
[3 4]
[5 6]]
在行方向合併:
[[1 2 5]
[3 4 6]]

3.array分割

數組的拆分,分為在垂直方向拆分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))

運行結果:

[[ 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]])]

當然,也可以使用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))

運行結果:

[[ 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中數組的賦值操作,默認是不進行拷貝的。下面例子中,arr1 和arr2指向了內存中的同一內存地址,是不同變量指向了同一對象。

import numpy as np
# 創建數組arr1
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 把數組arr1賦值給數組arr2,
arr2 = arr1
print(arr1)
print(arr2)
# arr1和arr2是否同一對象
print(arr1 is arr2)

運行結果:

[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
True

通過一個變量修改數組的值,由於兩個數組變量指向同一對象,所以另一處的值也是被修改後的:

# 上接
arr1[1][1] = 15
print(arr1)
print(arr2)

運行結果:

[[ 1 2 3]
[ 4 15 6]]
[[ 1 2 3]
[ 4 15 6]]

上面例子中,之前一處兩個變量指向的同一數組,數據發生了變化。是因為arr2 = arr1這句賦值操作默認採用的不拷貝。,如果,我想讓arr1和arr2是獨立的存在,當一處修改,另一處數據不變動。那麼只需要賦值時採用copy複製一份即可。代碼如下:

import numpy as np
# 創建數組arr1
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
# 把數組arr1賦值給數組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)

運行結果:

[[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()複製後,arr2和 arr1就相互獨立,一個數據修改不再影響另一個數組中的數據了。

索引操作

numpy中數組是矩陣的基礎,兩種可以相互轉化。數組操作中,索引的處理決定了操作哪些元素,因此索引操作變得至關重要。

一維數組,形如arr1=[0, 1, 2, 3, 4],arr1[1]拿到的是元素1;

一維數組,形如

[[ 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];

方差、標準差

numpy提供了計算方差、標準差的函數,在統計計算時非常有用:

計算數組的極差:np.pth(a)=max(a)-min(a)

計算方差(總體方差):np.var(a)

標準差:np.std(a)

import numpy as np
arr = np.arange(15).reshape((3, 5))
print(arr)
# 方差
print(np.var(arr))
# 標準差
print(np.std(arr))

運行結果:

[[ 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為橫軸長度,返回多項式的係數

多項式求導函數:np.polyder(poly),返回導函數的係數

得到多項式的n階導函數:多項式.deriv(m = n)

多項式求根:np.roots(poly)

多項式在某點上的值:np.polyval(poly,x[n]),返回poly多項式在橫軸點上x[n]上的值

兩個多項式做差運算: np.polysub(a,b)

線性代數基礎運算

估計線性模型中的係數: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)

概率分佈

產生二項分佈的隨機數:np.random.binomial(n,p,size=…),其中n,p,size分別是每輪試驗次數、概率、輪數

產生超幾何分佈隨機數:np.random.hypergeometric(n1,n2,n,size=…),其中參數意義分別是物件1總量、物件2總量、每次採樣數、試驗次數

產生N個正態分佈的隨機數:np.random.normal(均值,標準差,N)

產生N個對數正態分佈的隨機數:np.random.lognormal(mean,sigma,N)

小結

本文學習了numpy的常用用法,具體包括:如何安裝及導入numpy、數組的重要屬性、數組的多種創建方式、數組的常見操作、數組的合併、拆分;索引操作、多項式、方差、標準差、概率分佈等知識。這一節知識是後面學習Pandas和TensorFlow的基礎,務必掌握。


分享到:


相關文章: