【问题标题】:Fastest way to extract elements from a multi-dimensionnal array at specified array of indices从指定索引数组的多维数组中提取元素的最快方法
【发布时间】:2020-11-17 14:26:46
【问题描述】:

假设我有一个 n 维数组 A,其中有一个任意 n:

a = np.arange(3*4*5*...).reshape((3, 4, 5, ...))

...而且我有一个索引数组(正是这个形状或转置的):

ix = np.array([
  [0,1,1,...],
  [0,0,1,...],
  [1,0,1,...],
])

从 ix 的 at 索引中获取元素数组的最快方法是什么?

(例如最快的获取方式:

def take_at(a, ix):
  res = np.empty((ix.shape[0],*a.shape[ix.shape[1]:]))
  for i in range(ix.shape[0]):
    res[i,...] = a[(*ix[i],)]
  return res

...仅使用(如果可能的话)numpy 向量化函数/循环/操作?)

用于测试的简单复制粘贴示例::

a = np.arange(3*4*5).reshape((3,4,5))

ix = np.array([
  [0,1,1],
  [0,0,1],
  [1,0,1],
])

def take_at(a, ix):
  res = np.empty((ix.shape[0],*a.shape[ix.shape[1]:]), dtype=a.dtype)
  for i in range(ix.shape[0]):
    res[i,...] = a[(*ix[i],)]
  return res

take_at(a, ix)

【问题讨论】:

  • a[ix] 不起作用?
  • 不,a[ix] 像切片一样工作

标签: python numpy


【解决方案1】:

你需要将ix打包成一个元组:

take_at(a, ix)
Out[]: array([ 6,  1, 21])

a[tuple(ix.T)]
Out[]: array([ 6,  1, 21])

【讨论】:

  • 即使有数千个索引,tuple() 迭代是否很快? (因为元组是一个 python 对象,我想知道它是否会变慢)
  • python 中获得的速度很快,索引例程在c 中编译,因此比在python 循环中迭代要快得多
  • 如果其他帖子更快,我会等待,但我会标记它已解决
【解决方案2】:

你可以这样做:

a[ix[:,0],ix[:,1],ix[:,2]]

输出:

array([ 6,  1, 21])

【讨论】:

  • 我需要任意动态维度数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-29
  • 2021-09-03
  • 2021-08-15
  • 2020-04-19
相关资源
最近更新 更多