【问题标题】:How to unpack a tuple when indexing?索引时如何解包元组?
【发布时间】:2019-11-24 01:53:11
【问题描述】:

我有一个非常高维的张量,比如形状为 5 X 10 X 100 X 200 X 50 的 A。 我有一个返回元组 T 的一些 numpy 表达式,其中包含我想从 A 中提取的元素的索引。

我正在尝试这个:

A[*T]

上面写着:

语法无效,此处不能使用星号表达式。

我该怎么做? PS:长解是:A[T[0], T[1], T[2], T[3], T[4]]

编辑:我刚刚发现没有必要这样做,因为它是自动完成的。示例:

a= np.random.rand(3,3)
a[np.triu_indices(3)]

表达式np.triu_indices(3) 在作为索引传递给a 时会自动解包。 但是,回到我的问题并没有发生。具体来说,举个例子:

a = np.random.rand(100, 50, 14, 14)
a[:, :, np.triu_indices(14)].shape

假设最后一位np.triu_indices(14) 应该作用在最后两个轴上,就像前面的例子一样,但它并没有发生,并且产生的形状很奇怪。为什么不拆包?以及如何做到这一点?

【问题讨论】:

  • A[T]A[tuple(T)] 不起作用吗?
  • T 已经是一个元组,所以采用元组的元组将无济于事。 A[T] 适用于 2D 矩阵,但对于高阶张量,它的行为很奇怪。
  • 它独立于维度工作。也许您观察到的与结合高级和基本索引docs.scipy.org/doc/numpy/reference/… 相关?
  • @norok2 是的,这正是我正在做的。沿着前两个轴,我使用切片,沿着最后两个轴,我正在传递索引。
  • Python 3 为 * 解包增加了很多功能,但在索引表达式中是不允许的——至少不是直接的。 a[1,2,*(3,4)] 引发语法错误a[(1,2,*(3,4)] 扩展为 a[(1,2,3,4)] 或等效的 a[1,2,3,4])

标签: python numpy


【解决方案1】:

问题:

a[:, :, np.triu_indices(14)]

是您将[...] 的参数用作slicetuple (tuple(slice, slice, tuple(np.ndarray, np.ndarray))) 混合类型的元组,而不是单个tuple(最终使用高级索引),例如tuple(slice, slice, np.ndarray, np.ndarray)。 这给你带来了麻烦。我不会详细说明您的情况。

将该行更改为:

a[(slice(None),) * 2 + np.triu_indices(14)]

将解决您的问题:

a[(slice(None),) * 2 + np.triu_indices(14)].shape
# (100, 50, 105)

请注意,有几种重写方法:

(slice(None),) * 2 + np.triu_indices(14)

另一种可能是:

(slice(None), slice(None), *np.triu_indices(14))

【讨论】:

  • 我没听明白,抱歉。什么是连片?那是关键字吗?是什么 [...] ?我认为我的表达是完全合法的 a[:, :, np.triu_indices(14)] ?请用外行的话详细说明答案。
  • 基本上,:slice(None) 的语法糖,请参阅:docs.python.org/3/library/functions.html#slicestackoverflow.com/questions/31501806/… 了解更多信息。
  • 那是天才。谢谢。
  • 顺便说一句,你说“我不会详细说明正在发生的事情”。其实很简单。元组被认为是:我希望这个轴以两种方式切片。这就是为什么在结果中出现了一个额外的维度。 (100, 50, 2, 105, 14) 2 号!虽然最后一个维度(14)保持不变,因为我们没有传递任何关于它的信息。这很有见地,告诉您可以在一条线中以多种方式切割一个轴!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2020-12-25
  • 2019-04-21
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多