Python数据分析(5)-numpy数组索引

numpy数组的索引遵循python中x[obj]模式,也就是通过下标来索引对应位置的元素。在numpy数组索引中,以下问题需要主要: 1)对于单个元素索引,索引从0开始,也就是x[0]是第一个元素,x[n-1]对应第n个元素,最后一个元素为x[d-1],d为该维度的大小。 2)对于多个元素索引,索引也是从0开始,但是不包含最后一个索引值对应的元素,属于前闭后开区间索引,x[2,5]表示x的第3,4,5三个元素。 3)对于多个维度索引,维度之间用,(逗号隔开),例如X[1:3,4:6] 。 4)支持切片索引。 5)支持布尔值索引。 6)支持负数索引,-a代表d-a位置,d为该维度大小,例如-1代表最后一个元素的索引。 7)支持空位置,例如 x[:3]代表3前面所有的元素,但是不包括3 x[2:]表示2后面所有元素,并包含2。

1. 基础索引

1.1 单元素和多元素索引

import numpy as np 
a = np.arange(24)
a.shape=(2,3,4)
print('a 数据为:',a)

# 单元素索引,
b = a[0,1,3]
print('b is:',b)

# 多元素索引
c = a[:,:2,1:3]
print('c is:', c)
d = a[ ...,:2,1:3]
print('d is:',d)

输出:

a 数据为: [[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
b is: 7
c is: [[[ 1  2]
  [ 5  6]]

 [[13 14]
  [17 18]]]
d is: [[[ 1  2]
  [ 5  6]]

 [[13 14]
  [17 18]]]

notes: …和: 都可以表示该维度的所有元素

1.2 通过负数索引

通过负数索引,需要注意以下问题:(注意看c的区别) 1)冒号(:)后面的值实际位置一定要大于冒号前的位置,否则返回为空,也就是不能倒序索引(有其他办法解决) 2)要想倒序索引,则切片顺序要改为-1,例如:x[-1:1:-1]

import numpy as np 
a = np.arange(24)
a.shape=(4,6)
print('a 数据为:',a)

b = a[-2,-3]
print('b is:',b)

c1 = a[0:-2,2]
print('c1 is',c1)

c2 = a[-2:0,2]
print('c2 is',c2)
c3 = a[-4:-2,2]
print('c3 is',c3)

d = a[-1:0:-2,-2:0:-2]
print('d is:', d)

输出:

a 数据为: [[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
b is: 15
c1 is [2 8]
c2 is []
c3 is [2 8]
d is: [[22 20]
 [10  8]]

综上:在基础 索引中都是采用的python切片形式:x[start:stop:step] ,结合负数索引,可以从后向前,当step为负数时,则为倒序索引。

1.3 注意索引时的维度变化

import numpy as np 
a = np.arange(9)
a.shape=(3,3)
print('a 数据为:',a)

b = a[2,:]
print('b 的 shape is:',b.shape)

c = a[2:3,:]
print('c的shape is',c.shape)

输出: a 数据为: [[0 1 2] [3 4 5] [6 7 8]] b 的 shape is: (3,) c的shape is (1, 3)

a 数据为: [[0 1 2]
 [3 4 5]
 [6 7 8]]
b 的 shape is: (3,)
c的shape is (1, 3)

注意b和c的区别,当该维度是单个数时,会丢失该维度,所以b变为1维了,如果要保持维度不变,一定要采取c的索引形式,哪怕只有只需要该维度的一个元素。

2. 高级索引

基础所以通过切片的方式索引,而高级索引每一个维度上的索引下标可以为矩阵。高级索引有两种方式:整数索引和bool值索引

2.1 bool索引

bool索引的本质就相当于mask,索引数组的维度大小与原数组一样,返回索引数组中为Ture的位置对应的值,并压平为一维数组。

import numpy as np 
a = np.arange(9)
a.shape=(3,3)
print('a 数据为:',a)
ind = a > 5
print('ind is :', ind)
b = a[ind]
print('b  is:',b)
print( 'shape of b is:',b.shape)
a[ind] = 1
print(a)
a[ind] = [1,2,3]
print(a)

输出:

a 数据为: [[0 1 2]
 [3 4 5]
 [6 7 8]]
ind is : [[False False False]
 [False False False]
 [ True  True  True]]
b  is: [6 7 8]
shape of b is: (3,)
[[0 1 2]
 [3 4 5]
 [1 1 1]]
[[0 1 2]
 [3 4 5]
 [1 2 3]]

同样,也可以通过bool索引去对数组赋值。

2.2 整数索引

整数索引是说可以用数组去索引,规则符合numpy的boadcast规则,也就是每一维度的索引数组会相互组合。

import numpy as np 
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
ind = np.array([1,3])
print(a[ind])

输出:

a 数据为: [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
[[[ 4  5  6  7]
  [12 13 14 15]]]

因为只有第一维度给出了索引数组,所以第二维度完全保留,因而结果返回的是第二行和第四行。

import numpy as np 
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
row = np.array([[1,3],[3,1]])
col = np.array([[0,2],[2,1]])
print('index value is :', a[row,col])

输出:

a 数据为: [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
index value is : [[ 4 14]
 [14  5]]

采用boardcast方式,两个维度的索引矩阵对饮元素组合:(1,0),(3,2),(3,2),(1,1),故返回该结果。且返回结果的数组维度不变。 这种方式必须保证:索引数组的维度以及每一维度的大小一样,才能应用boardcast规则。

2.3 合理使用ix_() 函数

ix_函数是用来扩充维度,因为在整数索引中要保证每个维度的索引数组的维度一样,则可以直接用ix_函数来构建索引函数

import numpy as np 
a = np.arange(16)
a.shape=(4,4)
print('a 数据为:',a)
row = np.array([1,3])
col = np.array([0,2])
print('index value is :', a[np.ix_(row),np.ix_(col)])

输出:

a 数据为: [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
index value is : [[ 4 14]]

组合应该为(1,0),(3,2)位置的元素,返回两个值。可以发现,重复元素不返回。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券