《利用pyhton進(jìn)行數(shù)據(jù)分析》筆記-Numpy(二)

1.數(shù)組的索引和切片(可類比于list的索引和切片,注意區(qū)別)

數(shù)組選取數(shù)據(jù)子集或單個(gè)元素的方式有很多。一維數(shù)組跟list很相似,多維數(shù)組的花樣更多, 下面來(lái)看。

1. 1基本的索引和切片

先來(lái)看一下例子,體會(huì)一下一維數(shù)組與list的區(qū)別:

import numpy as np
temp_array = np.arange(15)  # array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
temp_list = list(range(15)) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

# 索引比較
temp_array[10]  #返回值: 10 
temp_list[10]   #返回值: 10 

# 切片比較
temp_array[1:5]  #返回值 array([1, 2, 3, 4])
temp_list[1:5]  #返回值 [1, 2, 3, 4]

# 對(duì)單個(gè)值賦值比較
temp_list[1] = 6
temp_list # 返回值  [0, 6, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
temp_array[1] = 6
temp_array # 返回值  array([ 0,  6,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

# 對(duì)切片賦值比較
temp_array[1:5] = 6
temp_array  # 返回值   array([ 0,  6,  6,  6,  6,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
# temp_list[1:5] = 6 # 報(bào)錯(cuò)  TypeError: can only assign an iterable

# 切片之后索引賦值比較
#先來(lái)看list
temp_list2 = temp_list[1:5] 
temp_list2 #  [6, 2, 3, 4]
temp_list2[2] = 1234
temp_list #返回值: [0, 6, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
temp_list2 # 返回值 [6, 2, 1234, 4]
temp_list[3] = 12341234  #對(duì)原始list修改
 temp_list2 # 返回值:[6, 2, 1234, 4]

#再來(lái)看array
temp_array2 = temp_array[2:8]
temp_array2 # array([6, 6, 6, 5, 6, 7])
temp_array2[2] = 1234
temp_array2 #返回值:array([   6,    6, 1234,    5,    6,    7])
temp_array # 返回值 array([   0,    6,    6,    6, 1234,    5,    6,    7,    8,    9,   10,11,   12,   13,   14])
temp_array[5] = 123123 # 對(duì)原始數(shù)組的修改
temp_array2 # 返回值: array([     6,      6,   1234, 123123,      6,      7])

通過(guò)看上邊的例子, 不難發(fā)現(xiàn)ndarray和list的索引、切片、對(duì)單個(gè)值賦值基本都一樣, 區(qū)別在于對(duì)切片直接賦值、切片單個(gè)值的賦值,list的切片賦值直接報(bào)錯(cuò),數(shù)組的切片修改,該值會(huì)自動(dòng)廣播到整個(gè)選區(qū)的元素。
ndarray切片是原始數(shù)組的視圖(可以理解為地址指向,類比于淺拷貝.),視圖上的任何修改都會(huì)直接反應(yīng)到原數(shù)組上,源數(shù)據(jù)的修改也會(huì)影響視圖。Numpy的這種做法其實(shí)不難理解,Numpy是用來(lái)處理大數(shù)據(jù)的,如果將其中的數(shù)據(jù)多次復(fù)制的話那得是多大的內(nèi)存和性能的消耗。
當(dāng)然,如果想要的得到的數(shù)組的切片是一個(gè)副本而不是視圖的話,需要進(jìn)行復(fù)制操作,即 temp_array[1:5].copy(),如果非必須,還是不要辣么做了!

來(lái)看一下多維數(shù)組的例子(拿二維為例):

# 二維:
temp_array5 = np.eye(4)
temp_array5
#返回值: array([[1., 0., 0., 0.],
#        [0., 1., 0., 0.],
#        [0., 0., 1., 0.],
#        [0., 0., 0., 1.]])

temp_array5[2]# 返回值:array([0., 0., 1., 0.])
temp_array5[2][2] # 返回值 1.0

temp_array5[:3] # [:3]的切片
# 返回值: array([[1., 0., 0., 0.],
#        [0., 1., 0., 0.],
#        [0., 0., 1., 0.]])

temp_array5[:3:2] # 類比于list,這就是[:3]的切片, 步長(zhǎng)為2
# 返回值: array([[1., 0., 0., 0.],
#        [0., 0., 1., 0.]])

temp_array5[:3] = 42 # 視圖賦值
temp_array5
#返回值:  array([[42., 42., 42., 42.],
#        [42., 42., 42., 42.],
#        [42., 42., 42., 42.],
#        [ 0.,  0.,  0.,  1.]])

temp_array5[1,2] = 88  #與 temp_array5[1][2] 一樣 
temp_array5
# 返回值:array([[42., 42., 42., 42.],
#            [42., 42., 88., 42.],
#            [42., 42., 42., 42.],
#              [ 0.,  0.,  0.,  1.]])
1.2切片索引

低維度的切片索引其實(shí)在1.1已經(jīng)用到過(guò)了, 現(xiàn)在咱們直接用多維的來(lái)為例:

temp_list = [[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]
temp_array = np.array(temp_list)
temp_array.shape # 返回值:  (2, 2, 3)

temp_array[1, :1] # 返回值 array([[7, 8, 9]])

temp_array[:2, :1] # array([[[1, 2, 3]],[[7, 8, 9]]])
# 注:相當(dāng)于temp_array[0][:1]與temp_array[1][:1] 的結(jié)合,不是相加,相加會(huì)廣播到元素級(jí)。

# 這里需要注意
temp_array[1,0,1] # 返回值 8

# temp_array[1,0,1]的元素和 temp_array[1,1,1]的元素組成的列表
temp_array[1,:,1] #array([ 8, 11])

# 請(qǐng)參考上一種請(qǐng)情況
temp_array[:,:,1] 
# 返回值:array([[ 2,  5],
#            [ 8, 11]])
temp_array[:,:,1]  = 110
temp_array
# array([[[  1, 110,   3],
#         [  4, 110,   6]],
#        [[  7, 110,   9],
#         [ 10, 110,  12]]])

# 注:只寫一個(gè)冒號(hào), 表示選取的對(duì)應(yīng)的整個(gè)維度。
1.3 布爾型索引

值的注意的是布爾型索引返回的值是副本而不是視圖,不是視圖?。?!

#數(shù)據(jù)準(zhǔn)備
temp_array1 = np.array('a b c d e f'.split(' '))
temp_array1 #array(['a', 'b', 'c', 'd', 'e', 'f'], dtype='<U1')
temp_array2 = np.random.randn(6,3)
temp_array2
# array([[-1.75405219, -0.33932199,  0.16753136],
#        [-0.40832969,  0.28943606, -0.29946825],
#        [-1.15116563, -1.93324644,  0.04890539],
#        [-2.55618941, -0.55516265,  0.13617437],
#        [ 2.11503851,  1.84211619,  0.35172968],
#        [ 0.75279809,  0.63056373, -1.1371636 ]])

# 單獨(dú)的判斷可以廣播到元素級(jí),這不是中點(diǎn), 布爾切片才是重點(diǎn)
temp_array1 == 'a' # 返回值 array([ True, False, False, False, False, False])
temp_array2>0
# array([[ True,  True,  True],
#        [False,  True, False],
#        [False, False,  True],
#        [False, False,  True],
#        [ True,  True,  True],
#        [ True,  True, False]])

temp_array2[temp_array1 == 'a'] #返回值:array([[-1.75405219, -0.33932199,  0.16753136]])


temp_array3 = temp_array2[temp_array1 == 'a']
temp_array2[0] = 5
temp_array3 #返回值:array([[-1.75405219, -0.33932199,  0.16753136]])
temp_array2
# array([[ 5.        ,  5.        ,  5.        ],
#        [-0.40832969,  0.28943606, -0.29946825],
#        [-1.15116563, -1.93324644,  0.04890539],
#        [-2.55618941, -0.55516265,  0.13617437],
#        [ 2.11503851,  1.84211619,  0.35172968],
#        [ 0.75279809,  0.63056373, -1.1371636 ]])

# 注: 這里返回的并不是視圖, 而是副本,是副本不是視圖 不是視圖。


# 可以寫為并列形式
temp_array2[(temp_array1 == 'a') | (temp_array1 == 'b')]
# 注:and 和or在布爾型數(shù)組中無(wú)效

# 返回值:array([[ 5.        ,  5.        ,  5.        ],
#        [-0.40832969,  0.28943606, -0.29946825]])

# 當(dāng)然還有這種形式
temp_array2[(temp_array1 == 'a'),:2] # array([[5., 5.]])
1.4 花式索引

花式索引是Numpy術(shù)語(yǔ),指的是利用整數(shù)數(shù)組進(jìn)行索引。返回的并不是視圖, 也是副本。

temp_array = np.eye(6)
temp_array[[1,2]]
# 返回值: array([[0., 1., 0., 0., 0., 0.],
#                [0., 0., 1., 0., 0., 0.]])

temp_array[[1,-2]]
# array([[0., 1., 0., 0., 0., 0.],
#        [0., 0., 0., 0., 1., 0.]])


temp_array[[1,-2],[1,2]] # 返回值 array([1., 0.]), 我擦, 這種看不出來(lái)啊, 咱們換一種

temp_array = np.arange(24).reshape((6,4))
temp_array
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [12, 13, 14, 15],
#        [16, 17, 18, 19],
#        [20, 21, 22, 23]])

temp_array[[1,2,3]]
# array([[ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [12, 13, 14, 15]])

temp_array[[1,2,3],[2,3,1]] #最終選取的元素是(1,2),(2,3), (3,1)返回值: array([ 6, 11, 13])

temp_array[[1,2,3]][:,[2,3,1]] # 這個(gè)是選取的方形區(qū)域, 注意以上兩種的寫法區(qū)別
# 返回值 array([[ 6,  7,  5],
#        [10, 11,  9],
#        [14, 15, 13]])

#注:花式索引返回的是副本, 而不是視圖。

2.數(shù)組的轉(zhuǎn)置和軸的對(duì)換

轉(zhuǎn)置是重塑的一種特殊形式,它返回的是源數(shù)據(jù)的視圖, 轉(zhuǎn)置最少要兩維。

#兩維數(shù)組
temp_array = np.arange(9).reshape((3,3))
# 兩維數(shù)組的轉(zhuǎn)置, 這兩種方式等價(jià) 
temp_array.transpose(1,0) 
# 返回值:array([[0, 3, 6],
#        [1, 4, 7],
#        [2, 5, 8]])

temp_array.T
# 返回值:array([[0, 3, 6],
#        [1, 4, 7],
#        [2, 5, 8]])


# 更高維度的數(shù)組轉(zhuǎn)置
temp_array2 = np.arange(27).reshape((3,3,3))
temp_array2
# 返回值:array([[[ 0,  1,  2],
#         [ 3,  4,  5],
#         [ 6,  7,  8]],

#        [[ 9, 10, 11],
#         [12, 13, 14],
#         [15, 16, 17]],

#        [[18, 19, 20],
#         [21, 22, 23],
#         [24, 25, 26]]])


temp_array2.transpose((1,0,2))
# 返回值:array([[[ 0,  1,  2],
#         [ 9, 10, 11],
#         [18, 19, 20]],

#        [[ 3,  4,  5],
#         [12, 13, 14],
#         [21, 22, 23]],

#        [[ 6,  7,  8],
#         [15, 16, 17],
#         [24, 25, 26]]])

temp_array2.transpose((1,2,0))

# 返回值:array([[[ 0,  9, 18],
#         [ 1, 10, 19],
#         [ 2, 11, 20]],

#        [[ 3, 12, 21],
#         [ 4, 13, 22],
#         [ 5, 14, 23]],

#        [[ 6, 15, 24],
#         [ 7, 16, 25],
#         [ 8, 17, 26]]])

temp_array2.T # 等價(jià)于 temp_array2.transpose((2,1,0))

#返回值: array([[[ 0,  9, 18],
#         [ 3, 12, 21],
#         [ 6, 15, 24]],

#        [[ 1, 10, 19],
#         [ 4, 13, 22],
#         [ 7, 16, 25]],

#        [[ 2, 11, 20],
#         [ 5, 14, 23],
#         [ 8, 17, 26]]])

是不是看的恍恍惚惚,迷迷瞪瞪.... 哈哈,我當(dāng)時(shí)看的時(shí)候也是如此,那下邊再來(lái)看一個(gè)例子(拿三維來(lái)講):

temp_array = np.arange(24).reshape((2,3,4))
temp_array # 原始數(shù)組
# 返回值:array([[[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]],

#        [[12, 13, 14, 15],
#         [16, 17, 18, 19],
#         [20, 21, 22, 23]]])


temp_array.transpose(1,0,2).shape # 返回值:(3, 2, 4)
temp_array.transpose(1,0,2)
# 返回值:array([[[ 0,  1,  2,  3],
#         [12, 13, 14, 15]],

#        [[ 4,  5,  6,  7],
#         [16, 17, 18, 19]],

#        [[ 8,  9, 10, 11],
#         [20, 21, 22, 23]]])



temp_array.transpose(1,2,0) # 其形狀為(3,4,2)

# 返回值:array([[[ 0, 12],
#         [ 1, 13],
#         [ 2, 14],
#         [ 3, 15]],

#        [[ 4, 16],
#         [ 5, 17],
#         [ 6, 18],
#         [ 7, 19]],

#        [[ 8, 20],
#         [ 9, 21],
#         [10, 22],
#         [11, 23]]])

temp_array.transpose(2,1,0)# 其形狀為(4,3,2)
#返回值: array([[[ 0, 12],
#         [ 4, 16],
#         [ 8, 20]],

#        [[ 1, 13],
#         [ 5, 17],
#         [ 9, 21]],

#        [[ 2, 14],
#         [ 6, 18],
#         [10, 22]],

#        [[ 3, 15],
#         [ 7, 19],
#         [11, 23]]])

從例子可以看出,數(shù)組的轉(zhuǎn)置是按照軸來(lái)轉(zhuǎn)換的,軸的編號(hào)即對(duì)應(yīng)維度的下標(biāo),比如原始數(shù)據(jù)temp_array的形狀(2,3,4),則0軸對(duì)應(yīng)的維度是2,即第一層中括號(hào)里的數(shù)據(jù),1號(hào)周對(duì)應(yīng)的維度是3,即第二層括號(hào)里的數(shù)據(jù),3軸對(duì)應(yīng)的維度是4,即第三層里的數(shù)據(jù),即元素。那么軸的轉(zhuǎn)換,比如原始數(shù)據(jù)(0,1,2),轉(zhuǎn)換為(1,0,2),也就是1號(hào)軸沿著0軸拼數(shù)據(jù), 然后組成形狀為 (3,2,4)的數(shù)據(jù), 咱們依次看圖:

原始數(shù)據(jù)
1號(hào)軸與0號(hào)軸轉(zhuǎn)置

注:temp_array.transpose(1,2,0)的數(shù)據(jù)可在temp_array.transpose(1,0,2)的基礎(chǔ)上求得在此不再展示。

2號(hào)軸與0號(hào)軸轉(zhuǎn)置

總注:本次筆記的內(nèi)容就到這里了,這次的重點(diǎn)是數(shù)組的索引、切片和轉(zhuǎn)置,轉(zhuǎn)置比較難理解, 我也是花了點(diǎn)功夫才理解其中的過(guò)程。后邊的通用函數(shù)以及利用數(shù)組進(jìn)行數(shù)據(jù)處理的內(nèi)容不再做筆記,這兩節(jié)主要講的是矢量化的一些內(nèi)容,一些方法用的時(shí)候直接查文檔就ok了,太零碎,記不住,請(qǐng)讀者老爺們見(jiàn)諒!最后需要提醒的是:注意區(qū)分視圖和副本的情況! 注意區(qū)分視圖和副本的情況!!注意區(qū)分視圖和副本的情況!??!

本人水平有限, 如有錯(cuò)誤歡迎提出指正!如有參考, 請(qǐng)注明出處!!原創(chuàng)不易,禁止抄襲,遇抄必肛?。?!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容