Python 數據分析三劍客之 NumPy(二):數組索引 / 切片 / 廣播 / 拼接 / 分割

CSDN 課程推薦:《Python 數據分析與挖掘》,講師劉順祥,浙江工商大學統計學碩士,數據分析師,曾擔任唯品會大數據部擔任數據分析師一職,負責支付環節的數據分析業務。曾與聯想、亨氏、網魚網咖等企業合作多個企業級項目。


NumPy 系列文章:


另有 Pandas、Matplotlib 系列文章已更新完畢,歡迎關注:


推薦學習資料與網站(博主參與部分文檔翻譯):



這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/104988137
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!

【1x00】認識 Numpy 中的 nan 和 inf

nan(NAN,Nan):全稱 not a number,即不是一個數字
inf(-inf,inf):全稱 infinity,inf 表示正無窮,-inf 表示負無窮

以下情況 Numpy 中會出現 nan:

  • 當讀取本地的文件爲 float 的時候,如果有缺失,就會出現 nan
  • 當做了一個不合適的計算的時候(如:無窮大減去無窮大)

以下情況會出現 inf 或者 -inf:

  • 比如一個數字除以 0,在 Python 中直接會報錯,但在 Numpy 中則是一個 inf 或者 -inf

指定一個 nan 或者 inf:

>>> import numpy as np
>>> a = np.nan
>>> b = np.inf
>>> print(a)
nan
>>> print(b)
inf
>>> type(a)
<class 'float'>
>>> type(b)
<class 'float'>

注意兩個 nan 並不相等,而兩個 inf 是相等的

>>> np.nan == np.nan
False
>>> np.inf == np.inf
True

nan 和任何值計算都爲 nan:

>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5])
>>> b = np.array([1, 2, np.nan, 4, np.nan])
>>> print(a+b)
[ 2.  4. nan  8. nan]

【1x01】判斷是否爲 nan 和 inf

  • isnan:判斷元素是否爲 nan(非數字)
  • isinf:判斷元素是否爲正無窮大或負無窮大
  • isposinf:判斷元素是否爲正無窮大
  • isneginf:判斷元素是否爲負無窮大
  • isfinite:判斷元素是否爲有限的(不是非數字,正無窮大和負無窮大中的一個)
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1.  2.  3.  4.]
 [nan  6.  7. nan]
 [ 9. nan 10. 11.]]
>>> np.isnan(a)
array([[False, False, False, False],
       [ True, False, False,  True],
       [False,  True, False, False]])

【1x02】統計數組中 nan 的個數

1、利用 np.count_nonzero 方法,結合兩個 nan 不相等的屬性,可以判斷數組中 nan 的個數:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1.  2.  3.  4.]
 [nan  6.  7. nan]
 [ 9. nan 10. 11.]]
>>> np.count_nonzero(a != a)    # 判斷 nan 的個數,a != a 即爲 nan,nan != nan
3

2、isnan() 方法可以判斷哪些是 nan,再結合 np.count_nonzero 方法可以判斷數組中 nan 的個數:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.nan, 6, 7, np.nan], [9 ,np.nan, 10, 11]])
>>> print(a)
[[ 1.  2.  3.  4.]
 [nan  6.  7. nan]
 [ 9. nan 10. 11.]]
>>> np.isnan(a)                        # np.isnan(a) 與 a != a 效果相同,判斷那些是 nan
array([[False, False, False, False],
       [ True, False, False,  True],
       [False,  True, False, False]])
>>> np.count_nonzero(np.isnan(a))
3

3、利用 collections 模塊的 Counter 方法來統計 nan 的個數(此方法僅適用於一維數組):

>>> from collections import Counter
>>> import numpy as np
>>> a = np.array([1, 2, np.nan, 4, np.nan])
>>> print(Counter(np.isnan(a)))
Counter({False: 3, True: 2})

【1x03】統計數組中 inf 的個數

1、isinf() 方法可以判斷哪些是 inf,再結合 np.count_nonzero 方法可以判斷數組中 inf 的個數:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, 11]])
>>> print(a)
[[  1.   2.   3.   4.]
 [ inf   6.   7. -inf]
 [  9. -inf  10.  11.]]
>>> np.isinf(a)
array([[False, False, False, False],
       [ True, False, False,  True],
       [False,  True, False, False]])
>>> np.count_nonzero(np.isinf(a))
3

2、利用 collections 模塊的 Counter 方法來統計 inf 的個數(此方法僅適用於一維數組):

>>> from collections import Counter
>>> import numpy as np
>>> a = np.array([1, 2, np.inf, 4, -np.inf])
>>> print(Counter(np.isinf(a)))
Counter({False: 3, True: 2})

【1x04】替換 inf 和 nan

numpy.nan_to_num() 方法可以將 nan 替換爲零,將 inf 替換爲有限數。

>>> import numpy as np
>>> a = np.array([[1, np.nan, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, np.nan]])
>>> print(a)
[[  1.  nan   3.   4.]
 [ inf   6.   7. -inf]
 [  9. -inf  10.  nan]]
>>> print(np.nan_to_num(a))
[[ 1.00000000e+000  0.00000000e+000  3.00000000e+000  4.00000000e+000]
 [ 1.79769313e+308  6.00000000e+000  7.00000000e+000 -1.79769313e+308]
 [ 9.00000000e+000 -1.79769313e+308  1.00000000e+001  0.00000000e+000]]

如果要將 nan 和 inf 替換成特定的值,則可以用以下方法:

>>> import numpy as np
>>> a = np.array([[1, np.nan, 3, 4], [np.inf, 6, 7, -np.inf], [9 ,-np.inf, 10, np.nan]])
>>> print(a)
[[  1.  nan   3.   4.]
 [ inf   6.   7. -inf]
 [  9. -inf  10.  nan]]
>>> loc_nan = np.isnan(a)
>>> loc_inf = np.isinf(a)
>>> a[loc_nan] = 111
>>> a[loc_inf] = 222
>>> print(a)
[[  1. 111.   3.   4.]
 [222.   6.   7. 222.]
 [  9. 222.  10. 111.]]

【2x00】NumPy 索引

【2x01】獲取具體元素

NumPy 的索引和 Python 列表的索引類似,可以通過中括號指定索引獲取第 i 個值(從 0 開始計數):

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

在多維數組中,可以用逗號分隔的索引元組獲取具體某個元素:

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> print(a)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>> print(a[1, 2])
6
>>> print(a[0, -2])
2
>>> a = np.array([[[1,2,3,4], [5,6,7,8]], [[9,10,11,12], [13,14,15,16]], [[17,18,19,20], [21,22,23,24]]])
>>> print(a)
[[[ 1  2  3  4]
  [ 5  6  7  8]]

 [[ 9 10 11 12]
  [13 14 15 16]]

 [[17 18 19 20]
  [21 22 23 24]]]
>>> print(a[0, 1, 2])
7
>>> print(a[1, 0, -1])
12

【2x02】獲取行或列

>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
>>> print(a[1])       # 取一整行
[4 5 6]
>>> print(a[1, :])    # 取一整行,效果同上
[4 5 6]
>>> print(a[1, ...])  # 取一整行,效果同上
[4 5 6]
>>> print(a[:, 2])    # 取一整列
[ 3  6  9 12]
>>> print(a[..., 2])  # 取一整列,效果同上
[ 3  6  9 12]
>>> print(a[1:3])     # 取多行
[[4 5 6]
 [7 8 9]]
>>> print(a[:, 0:2])  # 取多列
[[ 1  2]
 [ 4  5]
 [ 7  8]
 [10 11]]
>>> print(a[[1, 3], :])  # 取第一、三行和所有列
[[ 4  5  6]
 [10 11 12]]
>>> print(a[:, [0, 2]])  # 取第零、二列和所有行
[[ 1  3]
 [ 4  6]
 [ 7  9]
 [10 12]]

【2x03】布爾索引

除了直接獲取元素以外,還可以通過一個布爾數組來索引目標數組,即通過布爾運算(如:比較運算符)來獲取符合指定條件的元素的數組。

以下實例將篩選出大於 6 的元素:

>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
>>> print(a[a > 6])
[ 7  8  9 10 11 12]

以下實例使用取補運算符 ~ 來過濾掉 inf:

>>> import numpy as np
>>> a = np.array([1, 2, np.inf, 3, -np.inf, 4, 5])
>>> print(a)
[  1.   2.  inf   3. -inf   4.   5.]
>>> print(a[~np.isinf(a)])
[1. 2. 3. 4. 5.]

【2x04】花式索引

花式索引:傳遞一個索引數組來一次性獲得多個數組元素,花式索引總是將數據複製到新數組中。

花式索引根據索引數組的值作爲目標數組的某個軸的下標來取值。對於使用一維整型數組作爲索引,如果目標是一維數組,那麼索引的結果就是對應位置的元素;如果目標是二維數組,那麼就是對應下標的行。

花式索引結果的形狀與索引數組的形狀一致,而不是與被索引數組的形狀一致。

一維數組中的應用:

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

二維數組中的應用:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print([a[0, 1], a[1, 2], a[2, 3]])
[2, 7, 12]
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> row = np.array([0, 1, 2])       # 行
>>> col = np.array([1, 2, 3])       # 列
>>> print(a[row, col])
[ 2  7 12]

【3x00】NumPy 切片

Ndarray 數組對象基於 0 - n 的下標進行索引,與 Python 中列表的切片操作一樣,NumPy 的切片也可以通過冒號分隔切片參數 [start:stop:step] 來進行切片操作,另外,NumPy 也提供了一個內置函數 slice(start, stop, step) 來進行切片操作。

slice 方法應用:

>>> import numpy as np
>>> a = np.arange(10)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> b = slice(2, 8, 2)    # 從索引 2 開始到索引 8 停止,步長爲 2
>>> print(a[b])
[2 4 6]

通過冒號分隔切片參數 [start:stop:step] 來進行切片:

>>> import numpy as np
>>> a = np.arange(12)
>>> print(a)
[ 0  1  2  3  4  5  6  7  8  9 10 11]
>>> print(a[1:9:2])        # 從索引 1 開始到索引 9 停止,步長爲 2
[1 3 5 7]
>>> print(a[5:])
[ 5  6  7  8  9 10 11]     # 從索引 5 開始一直到最後一個元素

二數組中的切片,格式類似於 a[start:stop:step, start:stop:step],以逗號來分割行與列。

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8 ,9], [10, 11, 12], [13, 14, 15], [16, 17, 18]])
>>> print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]
 [13 14 15]
 [16 17 18]]
>>> print(a[0:4:2])       # 按照行從索引 0 開始到索引 4 停止,步長爲 2
[[1 2 3]
 [7 8 9]]
>>> print(a[0:4:2,...])   # 與上述方法相同,... 與 : 作用相同
[[1 2 3]
 [7 8 9]]
>>> print(a[...,1:])      # 按照列從索引 1 開始一直到最後一個元素
[[ 2  3]
 [ 5  6]
 [ 8  9]
 [11 12]
 [14 15]
 [17 18]]
>>> print(a[1:5:2,1:])   # 分別按照行從索引 1 開始到索引 5 停止,步長爲 2,按照列從索引 1 開始一直到最後一個元素
[[ 5  6]
 [11 12]]

三數組中的切片,格式類似於 a[start:stop:step, start:stop:step, start:stop:step],以逗號來分割塊、行與列。

>>> import numpy as np
>>> a = np.array([[[1,2,3,4], [5,6,7,8]], [[9,10,11,12], [13,14,15,16]], [[17,18,19,20], [21,22,23,24]]])
>>> print(a)
[[[ 1  2  3  4]
  [ 5  6  7  8]]

 [[ 9 10 11 12]
  [13 14 15 16]]

 [[17 18 19 20]
  [21 22 23 24]]]
>>> print(a[1,:,0:2])   # 取索引爲 1 的塊數、所有行、索引爲 0 到 2 的列
[[ 9 10]
 [13 14]]
>>> print(a[1,:,:])     # 取索引爲 1 的塊數、所有行與列
[[ 9 10 11 12]
 [13 14 15 16]]
>>> print(a[1,...,:])   # ... 與 : 作用相同
[[ 9 10 11 12]
 [13 14 15 16]]

【4x00】NumPy 數組運算以及廣播原則

NumPy 數組與數之間、數組與數組之間都支持加減乘除的計算。

  • 對於數組與數之間的計算,由於 NumPy 的廣播機制,加減乘除都會對數組的每一個元素進行操作。

  • 對於數組與數組之間的計算,相同維度的,相同位置元素之間會進行計算,不同維度的,將自動觸發廣播機制。

廣播(Broadcast)原則:如果兩個數組的後緣維度(trailing dimension,即從末尾開始算起的維度)的軸長度相符,或其中的一方的長度爲 1,則認爲它們是廣播兼容的。廣播會在缺失和(或)長度爲 1 的維度上進行。

通俗理解,以下情況的兩個數組均可進行廣播:

1、兩個數組各維度大小從後往前比對均一致:

>>> import numpy as np
>>> a = np.ones((3, 4, 5))
>>> b = np.ones((4, 5))
>>> print((a+b).shape)
(3, 4, 5)
>>>
>>> 
>>> c = np.ones((3))
>>> d = np.ones((2, 3))
>>> print((c+d).shape)
(2, 3)
>>>
>>> 
>>> e = np.ones((3, 4, 5))
>>> f = np.ones((4, 2))
>>> print((e+f).shape)
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    print((e+f).shape)
ValueError: operands could not be broadcast together with shapes (3,4,5) (4,2) 
# 因爲 e 和 f 維度大小此前往後對比不一致,所以會拋出異常

2、兩個數組存在一些維度大小不相等時,在其中一個數組中,這個不相等的維度大小爲 1:

>>> import numpy as np
>>> a = np.ones((3, 4, 5))
>>> b = np.ones((4, 1))
>>> print((a+b).shape)
(3, 4, 5)
# 此時雖然 a 與 b 的維度大小此前往後對比不一致,但是 b 數組的這個維度大小爲 1,所以仍然可以相加

那麼當兩個數組之間可以進行廣播的時候,具體是怎樣廣播、怎樣計算的呢?以下通過代碼和圖解來更進一步理解廣播機制:

數組與數之間的運算:

>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5])
>>> print(a)
[1 2 3 4 5]
>>> print(a+1)     # 對數組每一個元素都 +1
[2 3 4 5 6]
>>> print(a-1)     # 對數組每一個元素都 -1
[0 1 2 3 4]
>>> print(a*2)     # 對數組每一個元素都 *1
[ 2  4  6  8 10]
>>> print(a/2)     # 對數組每一個元素都 /1
[0.5 1.  1.5 2.  2.5]

相同維度的數組與數組之間的運算:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> b = np.array([[11, 12, 13, 14, 15], [16, 17, 18, 19, 20]])
>>> print(a)
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]]
>>> print(b)
[[11 12 13 14 15]
 [16 17 18 19 20]]
>>> print(a+b)
[[12 14 16 18 20]
 [22 24 26 28 30]]
>>> print(b-a)
[[10 10 10 10 10]
 [10 10 10 10 10]]
>>> print(a*b)
[[ 11  24  39  56  75]
 [ 96 119 144 171 200]]
>>> print(b/a)
[[11.          6.          4.33333333  3.5         3.        ]
 [ 2.66666667  2.42857143  2.25        2.11111111  2.        ]]

不同維度的數組與數組之間的運算:

實例一:一個二維數組與一個一維數組相加,此時就會觸發廣播機制,代碼與圖解如下:

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> b = np.array([20, 20, 20])
>>> print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
>>> print(b)
[20 20 20]
>>> print(a+b)
[[21 22 23]
 [24 25 26]
 [27 28 29]
 [30 31 32]]

01

實例二:一個 4 行 3 列的二維數組與一個 4 行 1 列的二維數組相加,此時就會觸發廣播機制,代碼與圖解如下:

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> b = np.array([[1], [2], [3], [4]])
>>> print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
>>> print(b)
[[1]
 [2]
 [3]
 [4]]
>>> print(a+b)
[[ 2  3  4]
 [ 6  7  8]
 [10 11 12]
 [14 15 16]]

02

實例三:一個 3 塊 4 行 2 列,即 shape=(3, 4, 2) 的三維數組與一個 1 塊 4 行 2 列,即 shape=(1, 4, 2) 的三維數組相加,此時就會觸發廣播機制,代碼與圖解如下:

>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4], [5, 6], [7, 8]], [[9, 10], [11, 12], [13, 14], [15, 16]], [[17, 18], [19, 20], [21, 22], [23, 24]]])
>>> b = np.array([[[1, 2], [3, 4], [5, 6], [7, 8]]])
>>> print(a)
[[[ 1  2]
  [ 3  4]
  [ 5  6]
  [ 7  8]]

 [[ 9 10]
  [11 12]
  [13 14]
  [15 16]]

 [[17 18]
  [19 20]
  [21 22]
  [23 24]]]
>>> print(b)
[[[1 2]
  [3 4]
  [5 6]
  [7 8]]]
>>> print(a.shape)
(3, 4, 2)
>>> print(b.shape)
(1, 4, 2)
>>> print(a+b)
[[[ 2  4]
  [ 6  8]
  [10 12]
  [14 16]]

 [[10 12]
  [14 16]
  [18 20]
  [22 24]]

 [[18 20]
  [22 24]
  [26 28]
  [30 32]]]

03


這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/104988137
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!

【5x00】數組的拼接與元素的添加

【5x01】將數組轉換成列表,拼接完成再轉換成數組

數組的拼接,可以先將數組轉成列表,利用列表的拼接函數,如:append()、extend() 等進行拼接處理,然後再將列表轉成數組即可。

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> a_list = list(a)
>>> b_list = list(b)
>>> for i in b_list:
	a_list.append(i)

	
>>> a_list
[1, 2, 3, 4, 5, 6]
>>> a = np.array(a_list)
>>> a
array([1, 2, 3, 4, 5, 6])

【5x02】numpy.append()

numpy.append() 方法可以將一個數組附加到另一個數組的尾部,與 Python 列表中的 append 方法類似,僅支持兩個數組之間的拼接,不能一次性拼接多個數組。

基本語法:numpy.append(a, values, axis=None)

參數解釋:

參數 描述
a 被添加元素的目標數組
values 要添加元素的目標數組,即將該數組添加到 a 數組的尾部
如果指定了 axis 的值,則要求該數組的維度必須與 a 相同
axis 指定軸,按照指定軸的方向進行拼接
如果未指定軸,則在使用前會將 a 和 values 都展平

應用舉例:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.append(a, b))                 # 兩個一維數組進行拼接
[1 2 3 4 5 6]
>>> 
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> b = np.array([10, 11, 12])
>>> print(np.append(a, b))                 # 一維數組與二維數組進行拼接
[ 1  2  3  4  5  6  7  8  9 10 11 12]
>>> 
>>> a = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
>>> b = np.array([[13, 14, 15], [16, 17, 18]])
>>> print(np.append(a, b))                # 二維數組與三維數組進行拼接
[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18]
>>> print(type(np.append(a, b)))          # 拼接後的數組仍然是一個 ndarray 對象
<class 'numpy.ndarray'>

指定 axis 的值舉例(指定了 axis 的值,要求兩個數組的維度必須相同):

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.array([[7, 8, 9]])
>>> print(np.append(a, b, axis=0))       # a、b 均爲二維數組,指定 axis 值爲 0
[[1 2 3]
 [4 5 6]
 [7 8 9]]
>>>
>>> a = np.array([[1, 2, 3], [4, 5, 6]])
>>> b = np.array([7, 8, 9])
>>> print(np.append(a, b, axis=0))      # a 爲二維數組,b 爲一維數組,指定 axis 值爲 0,此時會報錯
Traceback (most recent call last):
  ...
  ...
ValueError: all the input arrays must have same number of dimensions, ...

【5x03】numpy.concatenate()

numpy.concatenate() 方法能夠一次完成多個相同形狀數組的拼接。該方法效率更高,適合大規模的數據拼接。

基本語法:numpy.concatenate((a1, a2, ...), axis=0)

參數解釋:

參數 描述
a1, a2, … 要拼接的多個數組,要求各數組形狀相同
axis 指定軸,按照指定軸的方向進行拼接,默認爲 0 軸

要求各數組形狀相同舉例:如果 axis=0,則要求 1 軸(豎軸)相同,如果 axis=1,則要求 0 軸(橫軸)相同。

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> b = np.array([[10, 11, 12], [13, 14, 15]])
>>> c = np.array([[16, 17, 18]])        # 三個二維數組的 1 軸(豎軸)相同
>>> print(np.concatenate((a, b, c)))    # 三個二維數組默認沿 0 軸(橫軸)進行拼接
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]
 [13 14 15]
 [16 17 18]]
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> b = np.array([[9, 10, 11], [12, 13, 14]])
>>> c = np.array([[15, 16], [17, 18]])          # 三個二維數組的 0 軸(橫軸)相同
>>> print(np.concatenate((a, b, c), axis=1))    # 三個二維數組沿 1 軸(豎軸)進行拼接
[[ 1  2  3  4  9 10 11 15 16]
 [ 5  6  7  8 12 13 14 17 18]]
>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> b = np.array([[9, 10, 11], [12, 13, 14]])
>>> c = np.array([[15, 16], [17, 18]])          # 三個二維數組的 0 軸(橫軸)相同
>>> print(np.concatenate((a, b, c), axis=0))    # 三個二維數組沿 0 軸(橫軸)進行拼接將會報錯
Traceback (most recent call last):
  ...
  ...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...

【5x04】numpy.stack()

numpy.stack() 方法用於沿新軸連接數組序列。

基本語法:numpy.stack(arrays, axis=0)

參數解釋:

參數 描述
arrays 相同形狀的數組序列
axis 返回數組中的軸,輸入數組將沿着該軸來進行堆疊

應用舉例:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.stack((a, b),axis=0))
[[1 2 3]
 [4 5 6]]
>>> print(np.stack((a, b),axis=1))
[[1 4]
 [2 5]
 [3 6]]
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> print(np.stack((a,b),axis=0))
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]
>>> print(np.stack((a,b),axis=1))
[[[1 2]
  [5 6]]

 [[3 4]
  [7 8]]]

【5x05】numpy.vstack()

numpy.vstack() 方法通過垂直堆疊來生成數組。

基本語法:numpy.vstack(tup)

參數解釋:tup:數組序列,如果是一維數組進行堆疊,則數組長度必須相同,其它數組除了第一個軸(axis=0)的長度可以不同外,其它軸的長度必須相同。

應用舉例:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> print(np.vstack((a,b)))
[[1 2 3]
 [4 5 6]]
>>> 
>>> b = np.array([4, 5])
>>> print(np.vstack((a,b)))       # 一維數組長度不一樣時將拋出異常
Traceback (most recent call last):
  ...
  ...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 2)
>>> print(np.vstack((a,b)))
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8],[9,10]])
>>> a.shape
(2, 2)
>>> b.shape
(3, 2)
>>> print(np.vstack((a,b)))    # 第一個軸(axis=0)可以不同,其它軸必須相同
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]]

【5x06】numpy.hstack()

numpy.hstack() 方法通過水平堆疊來生成數組。

基本語法:numpy.hstack(tup)

參數解釋:tup:數組序列,除了一維數組的堆疊可以是不同長度外,其它數組堆疊時,除了第二個軸(axis=1)的長度可以不同外,其它軸的長度必須相同。

應用舉例:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5])
>>> print(np.hstack((a,b)))
[1 2 3 4 5]
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6],[7,8]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 2)
>>> print(np.hstack((a,b)))
[[1 2 5 6]
 [3 4 7 8]]
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> b = np.array([[5,6,7],[8,9,10]])
>>> a.shape
(2, 2)
>>> b.shape
(2, 3)
>>> print(np.hstack((a,b)))       # 第二個軸(axis=1)可以不同,其它軸必須相同
[[ 1  2  5  6  7]
 [ 3  4  8  9 10]]

【5x07】numpy.dstack()

numpy.dstack() 方法會沿着第三個維度拼接數組。

基本語法:numpy.dstack(tup)

參數解釋:tup:數組序列,除了第三個軸(axis=2)的長度可以不同外,其它軸的長度必須相同。一維或二維數組必須具有相同的形狀。

應用舉例:

>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> b = np.array([[[9], [10]], [[11], [12]]])
>>> a.shape
(2, 2, 2)
>>> b.shape
(2, 2, 1)
>>> print(np.dstack((a,b)))     # a 與 b 的第三個軸(axis=2)一個是 2,另一個是 1,可以不同,但其他軸必須相同
[[[ 1  2  9]
  [ 3  4 10]]

 [[ 5  6 11]
  [ 7  8 12]]]
>>> import numpy as np
>>> a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
>>> b = np.array([[[9, 10], [11, 12]]])
>>> a.shape
(2, 2, 2)
>>> b.shape
(1, 2, 2)
>>> print(np.dstack((a,b)))    # a 與 b 的第一個軸(axis=0)不同,將會拋出異常
[[[ 1  2  9]
  [ 3  4 10]]

 [[ 5  6 11]
  [ 7  8 12]]]
>>> print(np.dstack((a,b)))
Traceback (most recent call last):
  ...
  ...
ValueError: all the input array dimensions for the concatenation axis must match exactly, ...

【5x08】以上幾種方法的區別

  • concatenate() 方法在 axis=0 的時候相當於 vstack() 方法;
  • concatenate() 方法在 axis=1 的時候相當於 hstack() 方法;
  • concatenate() 方法在 axis=2 的時候相當於 dstack() 方法;
  • concatenate() 方法不會生成一個新的維度,且數組的維度不一定相同,而 stack() 方法生成一個新的維度,並且要求所有數組形狀都要一樣。

concatenate() 方法與 stack() 方法比較:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> b = np.array([4, 5, 6])
>>> c = np.stack((a, b), axis=0)
>>> d = np.concatenate((a, b), axis=0)
>>> a.shape
(3,)
>>> b.shape
(3,)
>>> c.shape
(2, 3)
>>> d.shape
(6,)
>>> print(c)
[[1 2 3]
 [4 5 6]]
>>> print(d)
[1 2 3 4 5 6]

【5x09】numpy.insert()

numpy.insert() 方法沿指定軸在指定索引之前插入值。

基本語法:numpy.insert(arr, obj, values, axis=None)

參數解釋:

參數 描述
arr 原數組
obj 索引值,將在其之前插入值
values 要插入的值
axis 軸,將沿着該軸進行插入操作,如果未指定,則插入前,原數組會被展開,變爲一維數組

應用舉例:

>>> import numpy as np
>>> a = np.array([[1,2],[3,4],[5,6]])
>>> print(np.insert(a, 3, [0, 0]))          # 未指定 axis 參數,在插入之前原數組會被展開
[1 2 3 0 0 4 5 6]
>>> print(np.insert(a, 1, [0], axis = 0))   # 沿 0 軸廣播插入
[[1 2]
 [0 0]
 [3 4]
 [5 6]]
>>> print(np.insert(a, 1, 11, axis = 1))    # 沿 1 軸廣播插入
[[ 1 11  2]
 [ 3 11  4]
 [ 5 11  6]]

【5x10】numpy.r_

numpy.r_:rrow(行) 的縮寫,即按照行連接兩個矩陣,要求列數相等。

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3],[7, 8, 9]])
>>> b = np.array([[4, 5, 6],[1, 2, 3]])
>>> 
>>> np.r_[a, b]
array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6],
       [1, 2, 3]])

【5x11】numpy.c_

numpy.c_:ccolumn(列) 的縮寫,即按照列連接兩個矩陣,要求行數相等。

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3],[7, 8, 9]])
>>> b = np.array([[4, 5, 6],[1, 2, 3]])
>>> 
>>> np.c_[a, b]
array([[1, 2, 3, 4, 5, 6],
       [7, 8, 9, 1, 2, 3]])

【6x00】數組的分割與元素的刪除

【6x01】numpy.split()

numpy.split() 方法可以沿特定的軸將數組均等的分割爲子數組。如果不能等分,將拋出異常。

基本語法:numpy.split(ary, indices_or_sections, axis=0)

參數解釋:

參數 描述
ary 被分割的數組
indices_or_sections 如果是一個整數 N,則該數組將沿 axis 均分爲 N 個數組
如果是一維整數數組,則數組元素代表每個分割點位置(左閉右開),N 個分裂點會得到 N + 1 個子數組
axis 沿着哪個維度進行分割,默認爲 0,橫向分割;爲 1 時,縱向分割

應用舉例:

>>> import numpy as np
>>> a = np.arange(10)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> print(np.split(a, 5))              # 將數組分爲五個大小相等的子數組
[array([0, 1]), 
 array([2, 3]), 
 array([4, 5]), 
 array([6, 7]), 
 array([8, 9])]
>>>
>>> print(np.split(a, 4))              # 無法等分的情況下將拋出異常
Traceback (most recent call last):
  ...
  ...
ValueError: array split does not result in an equal division
>>>
>>> print(np.split(a, [4, 8]))        # 分割點爲索引 4 和 8 的位置,相當於 a[:4]、a[4:8]、a[8:]
[array([0, 1, 2, 3]), 
 array([4, 5, 6, 7]), 
 array([8, 9])]
>>>
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> print(np.split(a, 5, axis=1))     # 指定 axis=1,按照縱向分割數組
[array([[1], 
		[6]]),
 array([[2], 
 		[7]]),
 array([[3], 
 		[8]]),
 array([[4], 
 		[9]]),
 array([[ 5], 
 		[10]])]

【6x02】numpy.array_split()

numpy.array_split() 的用法和作用都與 split() 方法一致,都可以用一個整數或者整數列表來分割數組。

兩者的區別:如果輸入的是一個 int 類型的數字,那麼在 split() 方法中,數組必須是均等的分割,否則就會報錯,而在 array_split() 方法中是可以進行不均等的分割的。

基本語法:numpy.array_split(ary, indices_or_sections, axis=0)

參數解釋:

參數 描述
ary 被分割的數組
indices_or_sections 如果是一個整數 N,則該數組將沿 axis 分割爲 N 個數組,可以不是均分的
如果是一維整數數組,則數組元素代表每個分割點位置(左閉右開),N 個分裂點會得到 N + 1 個子數組
axis 沿着哪個維度進行分割,默認爲 0,橫向分割;爲 1 時,縱向分割

應用舉例:

>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6, 7])
>>> print(np.array_split(a, 3))
[array([1, 2, 3]), array([4, 5]), array([6, 7])]   # 可以是不均分的
>>>
>>> print(np.array_split(a, 4))
[array([1, 2]), array([3, 4]), array([5, 6]), array([7])]

【6x03】numpy.vsplit()

numpy.vsplit() 方法相當於 split() 方法在 axis=0 時的效果,即橫向分割數組。

基本語法:numpy.vsplit(ary, indices_or_sections)

參數解釋:

參數 描述
ary 被分割的數組
indices_or_sections 如果是一個整數 N,則該數組將沿 axis 分爲 N 個相等的數組
如果是一維整數數組,則數組元素代表每個分割點位置(左閉右開),N 個分裂點會得到 N + 1 個子數組

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
>>> print(np.vsplit(a, 2))
[array([[1, 2, 3], 
		[4, 5, 6]]),
 array([[ 7,  8,  9], 
 		[10, 11, 12]])]
>>>
>>> print(np.vsplit(a, [1, 3]))
[array([[1, 2, 3]]),
 array([[4, 5, 6], 
 		[7, 8, 9]]),
 array([[10, 11, 12]])]

【6x04】numpy.hsplit()

numpy.hsplit() 方法相當於 split() 方法在 axis=1 時的效果,即縱向分割數組。

基本語法:numpy.hsplit(ary, indices_or_sections)

參數解釋:

參數 描述
ary 被分割的數組
indices_or_sections 如果是一個整數 N,則該數組將沿 axis 分爲 N 個相等的數組
如果是一維整數數組,則數組元素代表每個分割點位置(左閉右開),N 個分裂點會得到 N + 1 個子數組

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> print(np.hsplit(a, 5))
[array([[1], 
		[6]]), 
 array([[2], 
 		[7]]),
 array([[3], 
 		[8]]),
 array([[4], 
 		[9]]),
 array([[ 5], 
 		[10]])]
>>>
>>> print(np.hsplit(a, [1, 3]))
[array([[1], 
		[6]]),
 array([[2, 3], 
 		[7, 8]]),
 array([[ 4,  5], 
 		[ 9, 10]])]

【6x05】numpy.dsplit()

numpy.dsplit() 方法相當於 split() 方法在 axis=2 時的效果,即沿第三軸將數組拆分爲多個子數組。

基本語法:numpy.dsplit(ary, indices_or_sections)

參數解釋:

參數 描述
ary 被分割的數組
indices_or_sections 如果是一個整數 N,則該數組將沿 axis 分爲 N 個相等的數組
如果是一維整數數組,則數組元素代表每個分割點位置(左閉右開),N 個分裂點會得到 N + 1 個子數組

應用舉例:

>>> import numpy as np
>>> a = np.arange(16).reshape(2, 2, 4)
>>> print(a)
[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]
>>> print(np.dsplit(a, 2))
[array([[[ 0,  1], 
		 [ 4,  5]], 
		 [[ 8,  9], 
		 [12, 13]]]), 
 array([[[ 2,  3], 
 		 [ 6,  7]], 
 		 [[10, 11], 
 		 [14, 15]]])]
>>>
>>> print(np.dsplit(a, [3, 6]))
[array([[[ 0,  1,  2], 
		 [ 4,  5,  6]], 
		 [[ 8,  9, 10], 
		 [12, 13, 14]]]),
 array([[[ 3], 
 		 [ 7]], 
 		 [[11], 
 		 [15]]]), 
 array([], shape=(2, 2, 0), dtype=int32)]

【6x06】numpy.delete()

numpy.delete() 方法返回一個從原數組中刪除了指定子數組的新數組。

基本語法:numpy.delete(arr,obj,axis=None)

參數解釋:

參數 描述
arr 原數組
obj 可以是切片、整數或整數數組形式,表示沿指定軸刪除的子數組的索引
當 obj 爲切片形式時,要用 np.s_[:] 的格式
axis 軸,將沿着該軸進行插入操作,如果未指定,則插入前,原數組會被展開,變爲一維數組

應用舉例:

>>> import numpy as np
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
>>> print(np.delete(a, 8))          # 未指定 axis 參數,在插入之前原數組會被展開,然後再刪除索引爲 8 的元素
[ 1  2  3  4  5  6  7  8 10 11 12]
>>>
>>> print(np.delete(a, 1, axis=0))  # 指定 axis=0,刪除索引值爲 1 即第二行
[[ 1  2  3  4]
 [ 9 10 11 12]]
>>>
>>> print(np.delete(a, 1, axis=1))  # 指定 axis=1,刪除索引值爲 1 即第二列
[[ 1  3  4]
 [ 5  7  8]
 [ 9 11 12]]
>>>
>>> print(np.delete(a, np.s_[:2], axis=1)) # 切片形式,刪除前兩列
[[ 3  4]
 [ 7  8]
 [11 12]]
>>>
>>> print(np.delete(a, [0, 2], axis=1))    # 數組形式,刪除索引值爲 0 和 2 的列
[[ 2  4]
 [ 6  8]
 [10 12]]

【6x07】numpy.unique()

numpy.unique() 方法用於去除數組中的重複元素。

基本語法:numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)

參數解釋:

參數 描述
arr 原數組,如果不是一維數組則會被展開爲一維數組
return_index 如果爲 true,則返回新列表元素在舊列表中的位置(下標),並以列表形式儲
return_inverse 如果爲 true,則返回舊列表元素在新列表中的位置(下標),並以列表形式儲
return_counts 如果爲 true,則返回去重數組中的元素在原數組中的出現次數
axis 指定軸

應用舉例:

未指定 axis 值,原數組將會被展開:

>>> import numpy as np
>>> a = np.array([1, 1, 2, 2, 3, 4, 5, 5])
>>> b = np.array([[1, 1], [2, 3], [3, 4]])
>>> print(np.unique(a))
[1 2 3 4 5]
>>> print(np.unique(b))
[1 2 3 4]

指定 axis 值:

>>> import numpy as np
>>> a = np.array([[1, 0, 1], [1, 0, 1], [2, 3, 2], [5, 6, 5]])
>>> print(a)
[[1 0 1]
 [1 0 1]
 [2 3 2]
 [5 6 5]]
>>> print(np.unique(a, axis=0))    # 刪除相同的行
[[1 0 1]
 [2 3 2]
 [5 6 5]]
>>> print(np.unique(a, axis=1))    # 刪除相同的列
[[0 1]
 [0 1]
 [3 2]
 [6 5]]

return_counts 爲 True 時,返回去重數組中的元素在原數組中的出現次數:

>>> import numpy as np
>>> a = np.array([1, 1, 1, 2, 2, 3, 4, 5, 5])
>>> print(np.unique(a, return_counts=True))
(array([1, 2, 3, 4, 5]), array([3, 2, 1, 1, 2], dtype=int64))
# 前一個 array 表示去重後的數組,後一個 array 表示每一個元素在原數組中出現的次數

這裏是一段防爬蟲文本,請讀者忽略。
本文原創首發於 CSDN,作者 TRHX。
博客首頁:https://itrhx.blog.csdn.net/
本文鏈接:https://itrhx.blog.csdn.net/article/details/104988137
未經授權,禁止轉載!惡意轉載,後果自負!尊重原創,遠離剽竊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章