# 索引:索引数组和布尔索引

# 参考

# 索引数组

  • numpy提供了比常规的python序列更多的索引工具。除了按整数和切片索引之外,还可以使用数组进行索引

  • 当被索引数组是一维时,最终结果与索引数组保持一致。

    >>> a = np.arange(12)**2  
    array([  0,   1,   4,   9,  16,  25,  36,  49,  64,  81, 100, 121], dtype=int32)
    >>> i = np.array( [ 1,1,3,8,5 ] )   #一个包含索引数据的数组
    >>> a[i]                          
    array([ 1,  1,  9, 64, 25])
    >>>
    >>> j = np.array( [ [ 3, 4], [ 9, 7 ] ] )     #一个二维索引数组
    >>> a[j]                # 最终结果和j的形状保持一致
    array([[ 9, 16],
           [81, 49]])
    
  • 当被索引数组是多维数组时,按照第一维进行索引。

    可以这么理解:从image中每拿出一个元素,比如第一个元素0,然后去palette中找第0个行元素,也就是[0,0,0],将[0,0,0]作为一个整体放在结果数组的第一个元素位置,如此类推,就得到了最终结果。

    >>> palette = np.array( [ [0,0,0],              
    ...                       [255,0,0],            
    ...                       [0,255,0],            
    ...                       [0,0,255],            
    ...                       [255,255,255] ] )     
    >>> image = np.array( [ [ 0, 1, 2, 0 ],        
    ...                     [ 0, 3, 4, 0 ]  ] )
    >>> palette[image]                          
    array([[[  0,   0,   0],
            [255,   0,   0],
            [  0, 255,   0],
            [  0,   0,   0]],
           [[  0,   0,   0],
            [  0,   0, 255],
            [255, 255, 255],
            [  0,   0,   0]]])
    
  • 可以提供多个索引参数

    这么理解:从i中拿一个数,再从j的相同位置拿一个数,组成一个索引坐标,再去a中找元素。这有个前提,就是i和j必须是同构的。

    >>> a = np.arange(12).reshape(3,4)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> i = np.array( [ [0,1],                      
    ...                 [1,2] ] )
    >>> j = np.array( [ [2,1],                      
    ...                 [3,3] ] )
    >>> a[i,j]   
    array([[ 2,  5],
           [ 7, 11]])
    >>> k = [i,j]
    >>> a[k]           # 等同于a[i,j]
    array([[ 2,  5],
           [ 7, 11]])
    >>>
    >>> a[i,2]
    array([[ 2,  6],
           [ 6, 10]])
    >>>
    >>> a[:,j]                        
    array([[[ 2,  1],
            [ 3,  3]],
           [[ 6,  5],
            [ 7,  7]],
           [[10,  9],
            [11, 11]]])
    
    

# 布尔索引

  • 使用布尔索引实际上就是显式地选择数组中需要哪些项,不需要哪些项。

    >>> a = np.arange(12).reshape(3,4)
    >>> b = a > 4
    >>> b   # 通过比较运算,b变成了一个由布尔值组成的数组
    array([[False, False, False, False],
           [False,  True,  True,  True],
           [ True,  True,  True,  True]])
    >>> a[b]        # 生成一个由True值对应出来的一维数组
    array([ 5,  6,  7,  8,  9, 10, 11])
    >>> a[b] = 0    # 所有a中大于4的元素被重新赋值为0
    >>> a
    array([[0, 1, 2, 3],
           [4, 0, 0, 0],
           [0, 0, 0, 0]])
    >>> a[a>4] = 0	# 上面操作的简写
    
  • 可以使用逻辑运算符| ~ &

    >>> a = np.arange(12).reshape(3,4)
    >>> a[~b]
    array([0, 1, 2, 3, 4])
    >>> (a<4)|(a>7)
    array([[ True,  True,  True,  True],
           [False, False, False, False],
           [ True,  True,  True,  True]])
    >>> a[(a<4)|(a>7)]
    array([ 0,  1,  2,  3,  8,  9, 10, 11])
    >>> (a>3)&(a<8)
    array([4, 5, 6, 7])
    
  • 切片中布尔索引的使用

    >>> a = np.arange(12).reshape(3,4)
    >>> b1 = np.array([False,True,True])           
    >>> b2 = np.array([True,False,True,False])    
    >>>
    >>> a[b1,:]                               
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>>
    >>> a[b1]                                   
    array([[ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>>
    >>> a[:,b2]                                
    array([[ 0,  2],
           [ 4,  6],
           [ 8, 10]])
    >>>
    >>> a[b1,b2]                                
    array([ 4, 10])