【问题标题】:More efficient way to find index of objects in Python array在 Python 数组中查找对象索引的更有效方法
【发布时间】:2017-07-23 16:47:48
【问题描述】:

我有一个非常大的 400x300x60x27 数组(我们称之为“A”)。我取了最大值,现在是一个名为“B”的 400x300x60 数组。基本上我需要找到'B'中每个值的'A'中的索引。我已经将它们都转换为列表并设置了一个 for 循环来查找索引,但是因为有超过 700 万个值,所以需要很长时间才能完成它。这就是我所拥有的:

B=np.zeros((400,300,60))
C=np.zeros((400*300*60))
B=np.amax(A,axis=3)
A=np.ravel(A)
A=A.tolist()
B=np.ravel(B)
B=B.tolist()
for i in range(0,400*300*60):
    C[i]=A.index(B[i])

有没有更有效的方法来做到这一点?它需要几个小时和几个小时,程序仍然停留在最后一行。

【问题讨论】:

  • 你想在整个 4D 数组中找到一个值,还是从它来自的 27 个元素中找到它?您需要每个元素一次点击还是所有点击?您有可以分享的用例吗?还是保密的?
  • 你在小型阵列上测试过吗?那些您可以实际看到正在发生的事情并尝试替代方法的地方?你看过argmax吗?
  • (我不能再编辑前一个了,但感觉就像是 400x300x60 体积上的 3x3x3 张量场,但这只是盲目猜测 - 但如果是这种情况,你可能会在每个体素的基础上寻找一些梯度/方向,然后你当然不想在整个数组中搜索,也许numpy.argmax 就是你要找的)

标签: python arrays numpy indexing


【解决方案1】:

你不需要 amax,你需要 argmax。在 argmax 的情况下,数组将只包含索引而不包含值,使用索引查找值的计算效率要好于反之亦然。

所以,我建议您只存储索引。在展平数组之前。

运行 A.argmax 而不是 np.amax,这将包含索引。 但在将其展平为一维之前,您需要使用一个映射函数,该函数也将索引变为一维。这可能是一个微不足道的问题,因为您只需要使用一些基本操作来实现这一点。但这也会消耗一些时间,因为它需要执行很多次。但这不会是一个搜索问题,并且会为您节省相当多的时间。

【讨论】:

  • argmax 确实有效,非常感谢!我一直在到处寻找我不知道为什么我以前没有找到它。
  • 由于我对 numpy 不太擅长,因此无法更新您的代码。您能否根据我的建议发布您获得的更新代码。这样,人们可以更好地理解它(我无法更新,因为我没有数据集,否则我无法测试它的效率)
【解决方案2】:

您将获得那些 argmax 索引,并且由于扁平化,您基本上转换为这些等值的线性索引。

因此,一种解决方案是将适当的偏移量添加到 argmax 索引中,逐步利用 broadcasting 在每个索引中添加,就像这样 -

m,n,r,s = A.shape
idx = A.argmax(axis=3)
idx += s*np.arange(r)
idx += r*s*np.arange(n)[:,None]
idx += n*r*s*np.arange(m)[:,None,None] # idx is your C output

或者,一种紧凑的表达方式是这样 -

m,n,r,s = A.shape
I,J,K = np.ogrid[:m,:n,:r]
idx = n*r*s*I + r*s*J + s*K + A.argmax(axis=3)

【讨论】:

  • 可以使用np.ravel_multi_index吗?
  • @hpaulj 为此,您需要沿前三个轴创建所有索引的网格,将它们堆叠成一个多维度的 ndarray,然后使用 ravel_multi_index。不要认为这会比发布的更有效。
  • 是的,我们仍然需要ogrid;它只是为我们做n*r*s 乘法:np.ravel_multi_index((I, J, K, idx), A.shape)
猜你喜欢
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 2015-08-19
  • 1970-01-01
相关资源
最近更新 更多