Numpy系列(四)- 索引和切片

Python 中原生的數組就支持使用方括號([])進行索引和切片操做,Numpy 天然不會放過這個強大的特性。python

 單個元素索引

1-D數組的單元素索引是人們指望的。它的工做原理與其餘標準Python序列同樣。它是從0開始的,而且接受負索引來從數組的結尾進行索引。數組

import numpy as np
a = np.arange(10)
a
Out[130]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a[3]
Out[131]: 3
a[-2]
Out[132]: 8

與Python原生的列表、元組不一樣的是,Numpy數組支持多維數組的多維索引。工具

a.shape
Out[133]: (10,)
a.resize(2, 5)
a
Out[135]: 
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
a[0, 1]
Out[136]: 1
a[1, 2]
Out[137]: 7
a[1]
Out[138]: array([5, 6, 7, 8, 9])
a[1][2]
Out[139]: 7

  x[1,-1] 的結果等於 x[1][-1],可是第二種狀況效率更低,由於第二種方式建立了一個臨時數組。spa

切片支持

可使用切片和步長來截取不一樣長度的數組,使用方式與Python原生的對列表和元組的方式相同。code

x = np.arange(10)
x[2:5]
Out[140]: array([2, 3, 4])
x[2:5]
Out[141]: array([2, 3, 4])
x[:-2]
Out[142]: array([0, 1, 2, 3, 4, 5, 6, 7])
x[1:7:2]
Out[143]: array([1, 3, 5])
y = np.arange(35).reshape(5,7)
y
Out[144]: 
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, 27],
       [28, 29, 30, 31, 32, 33, 34]])
y[1:5:2,:3]
Out[145]: 
array([[ 7,  8,  9],
       [21, 22, 23]])
y[1:5:2,::3]
Out[146]: 
array([[ 7, 10, 13],
       [21, 24, 27]])

  注意:使用切片不會複製內部數組數據,但也會生成原始數據的新視圖。對象

索引數組

Numpy數組能夠被其餘數組索引。對於索引數組的全部狀況,返回的是原始數據的副本,而不是一個獲取切片的視圖。blog

索引數組必須是整數類型。索引

x = np.arange(10,1,-1)
x
Out[147]: array([10,  9,  8,  7,  6,  5,  4,  3,  2])
x[np.array([1,3,4,])]
Out[148]: array([9, 7, 6])

 使用索引數組來對被索引數組進行索引後,會生成一個與索引數組形狀相同的新數組,只是這個新數組的值會用被索引數組中對應索引的值替代。class

x[np.array([3, 3, 1, 8])]

 布爾索引數組

使用(整數)索引列表時,須要提供要選擇的索引列表,最後生成的結果形狀與索引數組形狀相同;可是在使用布爾索引時,布爾數組必須與要編制索引的數組的初始維度具備相同的形狀。在最直接的狀況下,布爾數組具備相同的形狀:效率

y
Out[149]: 
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, 27],
       [28, 29, 30, 31, 32, 33, 34]])
b = y>20
b
Out[150]: 
array([[False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [False, False, False, False, False, False, False],
       [ True,  True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True]])
y[b]
Out[151]: array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])
y[y>20]
Out[152]: array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])

與整數索引數組的狀況不一樣,在布爾數組中,結果是1-D數組,其包含索引數組中的全部元素,對應於布爾數組中的全部真實元素。索引數組中的元素始終以行優先(C樣式)順序進行迭代和返回。結果也與y[np.nonzero(b)]相同。與索引數組同樣,返回的是數據的副本,而不是一個獲取切片的視圖。

若是y比b的維數更高,則結果將是多維的。例如:

b[:,5]
Out[153]: array([False, False, False,  True,  True])
y[b[:,5]]
Out[154]: 
array([[21, 22, 23, 24, 25, 26, 27],
       [28, 29, 30, 31, 32, 33, 34]])

  結構化索引工具

爲了便於數組形狀與表達式和賦值關係的匹配,能夠在數組索引中使用np.newaxis對象來添加大小爲1的新維。例如

y.shape
Out[155]: (5, 7)
y[:,np.newaxis,:].shape
Out[157]: (5, 1, 7)

  注意,在數組中沒有新的元素,只是維度增長。這能夠方便地以一種方式組合兩個數組,不然將須要明確重塑操做。例如:

x = np.arange(5)
x
Out[158]: array([0, 1, 2, 3, 4])
x[:,np.newaxis] + x[np.newaxis,:]
Out[159]: 
array([[0, 1, 2, 3, 4],
       [1, 2, 3, 4, 5],
       [2, 3, 4, 5, 6],
       [3, 4, 5, 6, 7],
       [4, 5, 6, 7, 8]])

  省略語法(三個點)能夠用於指示徹底選擇任何剩餘的未指定維度。若是數組z的形狀是(3,3,3,3),那麼z[1,...,2]等效於z[1,:,:,2]。例如:

z = np.arange(81).reshape(3,3,3,3)
z
Out[160]: 
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]]],
       [[[27, 28, 29],
         [30, 31, 32],
         [33, 34, 35]],
        [[36, 37, 38],
         [39, 40, 41],
         [42, 43, 44]],
        [[45, 46, 47],
         [48, 49, 50],
         [51, 52, 53]]],
       [[[54, 55, 56],
         [57, 58, 59],
         [60, 61, 62]],
        [[63, 64, 65],
         [66, 67, 68],
         [69, 70, 71]],
        [[72, 73, 74],
         [75, 76, 77],
         [78, 79, 80]]]])
z[1,...,2]
Out[161]: 
array([[29, 32, 35],
       [38, 41, 44],
       [47, 50, 53]])
z[1,:,:,2]
Out[162]: 
array([[29, 32, 35],
       [38, 41, 44],
       [47, 50, 53]])

  給被索引的數組賦值

可使用單個索引,切片,索引和布爾數組來選擇數組的子集來分配。分配給索引數組的值必須是形狀一致的(相同的形狀或可廣播到索引產生的形狀)。例如,容許爲切片分配常量:

x = np.arange(10)
x[2:7]
Out[163]: array([2, 3, 4, 5, 6])
x[2:7] = np.arange(5)
x
Out[164]: array([0, 1, 0, 1, 2, 3, 4, 7, 8, 9])
相關文章
相關標籤/搜索