一步步理解花式索引(fancy index)

前言

最近在看 yolov8 的源码的时候,第一次看到花式索引的使用,在那一行代码卡了半天的时间,从疑惑,到怀疑自我,再到愤怒,一时间无法理解,怎么有这么恶心的东西:

一个多维的数组或者是张量,使用多维数组和张量作为索引

这玩意有什么出现的必要吗?本来多维矩阵的操作已经麻烦到不行了,你索引再给我整个多维矩阵,简直逆天。

网上大多数关于花式索引的文章都是浅尝辄止,看了半天都没得到啥有用的信息,于是花了半天时间,自己测试了一下,终于理解了其中的操作。


因为 np.array 与 tensor 关于花式索引的操作都是一样的,为了省事,下面是使用的 numpy。

我们跳过一维的索引,直接进入正题,二维数组作为索引:

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

ab1 两个数组是

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 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]]]
b1:  [[2, 0], [0, 1]]

例一

如果我现在要求解:a[b1, :, :],就是将二维数组 b1 作为 a 的第一维度的索引:

  • 获得的结果是啥?
  • 维度是多少?

为了方便理解,我将自己摸索的推导过程逐步分解,这样大家都可以轻松看懂:

在这里插入图片描述
我们知道 a[n, :, :] 的维度是 [4, 5],根据推导的公式,不难看出来获得的结果维度是 [2, 2, 4, 5]
在这里插入图片描述

例二

这次我们求 a[:, b2, :]b2 的值如下, 看看有什么不一样的地方(其实也是一样的)。

b2 = np.array([[0, 0], [1, 2]])

在这里插入图片描述
在这里插入图片描述

例三

前面的例一和例二都是三维数组,但是都只选择其中一个维度进行花式索引,接下来我们升级一下,如果有两个维度都进行了花式索引,我们又会获得怎么样的结果捏?

这里我们继续沿用上面的数组 a,接下来我们要求解 a[b1, :, b2] 的结果。

这会涉及到一个广播机制,就是作为索引的 b1b2 都得满足广播机制得规则才行,他们会被转换成维度一致的矩阵。讲究一个门当户对,在这里就不做过多的介绍了。

在这里插入图片描述

代码

大家可以跑一下下面的代码,看看结果:

import numpy as np
a = np.arange(60).reshape((3, 4, 5))
b1 = [[2, 0], [0, 1]]
b2 = [[0, 0], [1, 2]]
example_1 = a[b1, :, :]
example_2 = a[:, b2, :]
example_3 = a[b1, :, b2]

print(example_1, example_1.shape)
print(example_2, example_2.shape)
print(example_3, example_3.shape)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值