NumPy 使用索引数组进行索引

2021-09-03 17:37 更新
  1. >>> a = np.arange(12)**2 # the first 12 square numbers
  2. >>> i = np.array([1, 1, 3, 8, 5]) # an array of indices
  3. >>> a[i] # the elements of `a` at the positions `i`
  4. array([ 1, 1, 9, 64, 25])
  5. >>>
  6. >>> j = np.array([[3, 4], [9, 7]]) # a bidimensional array of indices
  7. >>> a[j] # the same shape as `j`
  8. array([[ 9, 16],
  9. [81, 49]])

当索引数组a是多维时,单个索引数组指的是a的第一维。以下示例通过使用调色板将标签图像转换为彩色图像来展示此行为。

  1. >>> palette = np.array([[0, 0, 0], # black
  2. ... [255, 0, 0], # red
  3. ... [0, 255, 0], # green
  4. ... [0, 0, 255], # blue
  5. ... [255, 255, 255]]) # white
  6. >>> image = np.array([[0, 1, 2, 0], # each value corresponds to a color in the palette
  7. ... [0, 3, 4, 0]])
  8. >>> palette[image] # the (2, 4, 3) color image
  9. array([[[ 0, 0, 0],
  10. [255, 0, 0],
  11. [ 0, 255, 0],
  12. [ 0, 0, 0]],
  13. [[ 0, 0, 0],
  14. [ 0, 0, 255],
  15. [255, 255, 255],
  16. [ 0, 0, 0]]])

我们还可以为多个维度提供索引。每个维度的索引数组必须具有相同的形状。

  1. >>> a = np.arange(12).reshape(3, 4)
  2. >>> a
  3. array([[ 0, 1, 2, 3],
  4. [ 4, 5, 6, 7],
  5. [ 8, 9, 10, 11]])
  6. >>> i = np.array([[0, 1], # indices for the first dim of `a`
  7. ... [1, 2]])
  8. >>> j = np.array([[2, 1], # indices for the second dim
  9. ... [3, 3]])
  10. >>>
  11. >>> a[i, j] # i and j must have equal shape
  12. array([[ 2, 5],
  13. [ 7, 11]])
  14. >>>
  15. >>> a[i, 2]
  16. array([[ 2, 6],
  17. [ 6, 10]])
  18. >>>
  19. >>> a[:, j]
  20. array([[[ 2, 1],
  21. [ 3, 3]],
  22. [[ 6, 5],
  23. [ 7, 7]],
  24. [[10, 9],
  25. [11, 11]]])

在 Python 中,arr[i, j]arr[(i, j)]完全相同,因此我们可以将ij放入tuple 中,然后使用它进行索引。

  1. >>> l = (i, j)
  2. >>> # equivalent to a[i, j]
  3. >>> a[l]
  4. array([[ 2, 5],
  5. [ 7, 11]])

但是,我们不能通过将ij放入数组来做到这一点,因为该数组将被解释为索引a的第一维。

  1. >>> s = np.array([i, j])
  2. >>> # not what we want
  3. >>> a[s]
  4. Traceback (most recent call last):
  5. File "<stdin>", line 1, in <module>
  6. IndexError: index 3 is out of bounds for axis 0 with size 3
  7. >>> # same as `a[i, j]`
  8. >>> a[tuple(s)]
  9. array([[ 2, 5],
  10. [ 7, 11]])

数组索引的另一个常见用途是搜索时间相关序列的最大值:

  1. >>> time = np.linspace(20, 145, 5) # time scale
  2. >>> data = np.sin(np.arange(20)).reshape(5, 4) # 4 time-dependent series
  3. >>> time
  4. array([ 20. , 51.25, 82.5 , 113.75, 145. ])
  5. >>> data
  6. array([[ 0. , 0.84147098, 0.90929743, 0.14112001],
  7. [-0.7568025 , -0.95892427, -0.2794155 , 0.6569866 ],
  8. [ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
  9. [-0.53657292, 0.42016704, 0.99060736, 0.65028784],
  10. [-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
  11. >>> # index of the maxima for each series
  12. >>> ind = data.argmax(axis=0)
  13. >>> ind
  14. array([2, 0, 3, 1])
  15. >>> # times corresponding to the maxima
  16. >>> time_max = time[ind]
  17. >>>
  18. >>> data_max = data[ind, range(data.shape[1])] # => data[ind[0], 0], data[ind[1], 1]...
  19. >>> time_max
  20. array([ 82.5 , 20. , 113.75, 51.25])
  21. >>> data_max
  22. array([0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
  23. >>> np.all(data_max == data.max(axis=0))
  24. True

还可以将索引与数组一起用作分配给的目标:

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

然而,当索引列表包含重复时,赋值会进行多次,留下最后一个值:

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

这是合理的,但是如果你想使用 Python 的 +=构造,请注意,因为它可能不会达到您的预期:

  1. >>> a = np.arange(5)
  2. >>> a[[0, 0, 2]] += 1
  3. >>> a
  4. array([1, 1, 3, 3, 4])

即使 0 在索引列表中出现两次,第 0 个元素也只增加一次。这是因为 Python 需要a += 1等效于a = a + 1.

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号