一、 數組元素值的替換
我們可以使用索引或 where () 函數來替換 NumPy 數組中的元素值。
1.1 方式一:索引
import numpy as npnp.random.seed(42)a3 = np.random.randint(0, 10, size=(3, 4))print("原數組:\n", a3)a3\[1] = 0 # 將a3數組第一行數據全部更換為0print("替換后數組:\n", a3)a3\[1] = np.array(\[1, 2, 3, 4]) # 將a3數組第一行數據更換為 \[1, 2, 3, 4]print("再次替換后數組:\n", a3)
1.2 方式二:條件索引
import numpy as npnp.random.seed(42)a3 = np.random.randint(0, 10, size=(3, 4))print("原數組:\n", a3)a3\[a3 < 3] = 1 # 數組中值小于3的元素全部替換為1print("條件替換后數組:\n", a3)
1.3 方式三:where () 函數
import numpy as npnp.random.seed(42)a3 = np.random.randint(0, 10, size=(3, 4))print("原數組:\n", a3)result = np.where(a3 < 5, 0, 1) # 將a3數組中小于5的值替換為0,剩余值替換為1print("使用where()替換后數組:\n", result)
二、 數組的廣播機制
數組的廣播機制允許形狀不同的數組進行運算,只要它們的形狀是兼容的。廣播機制的基本原則是:如果兩個數組的后緣維度(從末尾開始算起的維度)的軸長度相同或其中一方的長度為 1,則認為它們是廣播兼容的。廣播會在缺失和(或)長度為 1 的維度上進行。
2.1 廣播原則
-
如果兩個數組的后緣維度的軸長度相同或其中一方的長度為 1,則認為它們是廣播兼容的。
-
廣播會在缺失和(或)長度為 1 的維度上進行。
示例:
-
shape 為 (3,8,2) 的數組能和 shape 為 (8,1) 的數組進行運算嗎?是。
-
shape 為 (3,1,8) 的數組能和 shape 為 (8,1) 的數組進行運算嗎?是。
2.2 數組與數字運算
import numpy as npa = np.random.randint(0, 5, size=(3, 5))print(a)a = a \* 2.345print(a.round(2)) # 數組中的所有元素都乘以2.345,并保留2位小數
2.3 數組與數組運算
import numpy as npa1 = np.random.randint(0, 5, size=(3, 5))a2 = np.random.randint(0, 5, size=(3, 5))print(a1 + a2) # 數組形狀一致時,各個元素相加減(滿足數組廣播機制)a3 = np.random.randint(0, 5, size=(3, 4))\# a1 + a3 # 報錯,形狀不一致的數組不能相加減(不滿足數組廣播機制)
三、 數組形狀的操作
3.1 數組形狀的改變
(1) reshape 與 resize
import numpy as npa1 = np.random.randint(0, 10, size=(3, 4))print(a1)a2 = a1.reshape((2, 6)) # reshape是將數組轉換成指定的形狀,然后返回轉換后的結果,原數組的形狀不會發生改變print(a2)a1.resize((4, 3)) # resize是將數組轉換成指定的形狀,會直接修改數組本身,并且不會返回任何值print(a1)
(2) flatten 與 ravel
import numpy as npa3 = np.array(\[\[6, 9, 1, 6], \[4, 9, 4, 8], \[7, 0, 6, 0]])print(a3)a4 = a3.flatten() # flatten將多維數組轉換為一維數組,并返回一個拷貝,后續對這個返回值的修改不會影響原數組a4\[0] = 100print("flatten后:", a4)print("原數組\[0,0]:", a3\[0, 0])a5 = a3.ravel() # ravel將多維數組轉換為一維數組,并返回一個視圖,后續對這個返回值的修改會影響原數組a5\[0] = 200print("ravel后:", a5)print("原數組\[0,0]:", a3\[0, 0])
3.2 數組的疊加
(1) 垂直方向疊加的兩種方式
import numpy as npv1 = np.random.randint(0, 10, size=(3, 4))v2 = np.random.randint(0, 10, size=(2, 4))v3 = np.vstack(\[v1, v2]) # 垂直方向疊加v4 = np.concatenate(\[v1, v2], axis=0) # 垂直方向疊加print(v3)print(v4)
(2) 水平方向疊加的兩種方式
import numpy as nph1 = np.array(\[\[5, 0, 8, 6], \[8, 5, 1, 8], \[4, 3, 6, 3]])h2 = np.array(\[\[4], \[5], \[3]])h3 = np.hstack(\[h1, h2]) # 水平方向疊加h4 = np.concatenate(\[h1, h2], axis=1) # 水平方向疊加print(h3)print(h4)
(3) 先將數據拉伸轉換成一維數組,再拼接
import numpy as npnp.random.seed(42)h1 = np.random.randint(0, 10, size=(3, 4))h2 = np.random.randint(0, 10, size=(3, 1))h5 = np.concatenate(\[h1, h2], axis=None) # 先拉伸轉換成一維數組,再拼接print(h5)
3.3 數組的切割
(1) 水平方向切割
import numpy as npnp.random.seed(42)hs1 = np.random.randint(0, 10, size=(3, 4))print(hs1)print(np.hsplit(hs1, 2)) # 水平方向平均分為2份(要求列數可被2整除)print(np.hsplit(hs1, (1, 2))) # 水平方向分為1,1,2列(在下標為1,2處切割)
(2) 垂直方向切割
import numpy as npvs1 = np.array(\[\[6, 3, 7, 4, 6], \[9, 2, 6, 7, 4], \[3, 7, 7, 2, 5], \[4, 1, 7, 5, 1]])print(vs1)print(np.vsplit(vs1, 4)) # 垂直方向平均分為4份print(np.vsplit(vs1, (1, 3))) # 垂直方向分為1,2,1份(在下標為1,3處切割)
(3) 指定切割方式
import numpy as nparr = np.array(\[\[1, 2, 7, 9], \[9, 7, 7, 8], \[3, 1, 2, 6]])print(np.split(arr, 4, axis=1)) # 按列平均切割print(np.split(arr, 4, axis=0)) # 按行平均切割
3.4 矩陣轉置
(1) 通過 ndarray.T 進行轉置
import numpy as npt1 = np.random.randint(0, 10, size=(3, 4))print(t1)print(t1.T) # 數組t1轉置print(t1.dot(t1.T)) # 矩陣相乘
(2) 通過 ndarray.transpose () 進行轉置
import numpy as npt2 = t1.transpose()t2\[0, 0] = 99 # 修改會影響原來的數組print(t2)print(t1)
四、 Axis 理解
在 NumPy 中,axis 是指數組的某個維度,用于指定對數組進行操作時沿著哪個維度進行操作。
4.1 Axis
axis 用于指定軸是行還是列,默認 axis=0。axis=0 代表沿著行的方向進行操作,axis=1 代表沿著列的方向進行操作。
(1) 求 x 數組在 axis=0 和 axis=1 兩種情況下的和
import numpy as npx = np.array(\[\[0, 1], \[2, 3]])print(x.sum(axis=0)) # 按列求和print(x.sum(axis=1)) # 按行求和
(2) 用 np.max 求 axis=0 和 axis=1 兩種情況下的最大值
import numpy as npnp.random.seed(100)x = np.random.randint(1, 10, size=(3, 5))print(x)print(x.max(axis=0)) # 按列求最大值print(x.max(axis=1)) # 按行求最大值
(3) 用 np.delete 在 axis=0 和 axis=1 兩種情況下刪除元素
import numpy as npnp.random.seed(100)x = np.random.randint(1, 10, size=(3, 5))print(x)print(np.delete(x, 0, axis=0)) # 刪除第0行print(np.delete(x, 0, axis=1)) # 刪除第0列