43.Python編程:NumPy詳解

前言

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ù)。

矩陣A

解析:在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]]

手動求解:


手動求解矩陣A的秩

3.求矩陣A的逆矩陣
說明:逆矩陣是對方陣定義的,因此逆矩陣一定是方陣。
逆矩陣:設(shè)A是數(shù)域上的一個n階矩陣,若在相同數(shù)域上存在另一個n階矩陣B,使得: AB=BA=E ,則我們稱B是A的逆矩陣,而A則被稱為可逆矩陣。注:E為單位矩陣。

矩陣A

解析:在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]]

手動計算:


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

4.求y = -2x^2 + 4x + 16的根,并求出其導(dǎo)函數(shù)

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

解析:為了形象展示多項式,我們借用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é)果:


多項式求根及一階導(dǎo)數(shù)

數(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.int32numpy.int16numpy.float64等。

  • ndarray.itemsize

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

complex32itemsize4(=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.int16np.int32np.int128
float系列包括:np.float64(默認(rèn))、np.float16np.float32np.float84np.float96np.float128np.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)建

numpyarrange()的用法和Pythonrange()一樣,我們可以直接傳入一個size,也可以指定起始值-結(jié)束值-步長,numpyarrange()還可以重新定義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)建

numpylinspace(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)
numpy中dtype類型
numpy數(shù)組生成函數(shù)匯總表

數(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

下面例子中,保持arr1shape(2, 3)不變;利用reshape()修改arr2shape(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ī)則如圖:


累和計算規(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.Tnp.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ù)制后,arr2arr1就相互獨立,一個數(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í)PandasTensorFlow的基礎(chǔ),務(wù)必掌握。

參考資料:NumPy官網(wǎng)教程(英文)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,990評論 2 374