【问题标题】:Determine the position of each element of an array B in another array A确定数组 B 的每个元素在另一个数组 A 中的位置
【发布时间】:2017-10-21 10:19:54
【问题描述】:

给定两个列表:

In [518]: A
Out[518]: [3, 4, 2, 1, 7, 6, 5]

In [519]: B
Out[519]: [4, 6]

B 中的每个元素都存在于A 中,无一例外。

我想检索 B 的索引数组,如 A 中所示。例如,A 中的索引 1 中存在 4,B 的位置 5 中存在 6。对于这种情况,我的预期输出是 [1, 5]

这是我为获取索引所做的:

In [520]: np.flatnonzero(np.in1d(a, b))
Out[520]: array([1, 5])

很遗憾,这在大多数其他情况下都不起作用。例如,如果B = [6, 4],我的方法在应该输出[5, 1]时仍然输出[1, 5]

有没有一种有效的 numpy 方法来获得我想要实现的目标?

【问题讨论】:

  • 很确定这以前出现过?重复呢?
  • np.where 的帮助给出了这个确切的例子:ix = np.in1d(A.ravel(), B).reshape(A.shape); np.where(ix)。抱歉,不符合您的第二个条件。
  • @p-robot 是的,此外,我的flatnonzero 方法更好一些。 ;-)
  • @Asterisk 是的,这个问题的灵感来自stackoverflow.com/questions/46862148/…,对 Martijn Pieters 的回答稍作修改就会给我我想要的 python 内容。我的问题更多是出于对“如何”的好奇。
  • @cᴏʟᴅsᴘᴇᴇᴅ 啊哈!我知道我以前见过那些 A 和 B:p

标签: python arrays numpy indexing


【解决方案1】:

IIUC:

In [71]: a
Out[71]: array([3, 4, 2, 1, 7, 6, 5, 6, 4])

In [72]: b
Out[72]: array([4, 6])

In [73]: np.where(a==b[:,None])[1]
Out[73]: array([1, 8, 5, 7], dtype=int64)

In [74]: b = np.array([6, 4])

In [75]: np.where(a==b[:,None])[1]
Out[75]: array([5, 7, 1, 8], dtype=int64)

更新:如果您只需要第一次次出现的索引(如果A 数组中有重复项),请使用this solution from @Divakar,这样会更快:

In [84]: (a==b[:,None]).argmax(1)
Out[84]: array([5, 1], dtype=int64)

【讨论】:

  • 感谢您的回复!我在第一个实例中寻找[1, 5],在第二个实例中寻找[5, 1]。你的答案似乎到了那里,但还没有到那里:-)
  • @cᴏʟᴅsᴘᴇᴇᴅ,我已经更改了你的 a 数组 ;-)
  • 天哪,我没有意识到。是的,这正是我要找的!非常感谢!
  • 如果just the first instance is needed,我猜你需要(a==b[:,None]).argmax(1)
  • @Divakar,是的,that additional condition 我完全同意 ;-)
【解决方案2】:

不知道有没有效率,但是

[int(np.isin(A, B[x]).nonzero()[0]) for x in range(len(B))]

似乎符合要求。如果不能保证唯一性,则可以删除 int() 部分

【讨论】:

  • 说实话,我自己也想过这个,但我想要的东西少一点……循环。
【解决方案3】:

如果 m=A.sizen=B.size where 方法是 O(mn) 。您可以通过仔细排序in1d 输出(此处具有唯一值)留在O((m+n)log(m+n))

A= np.unique(np.random.randint(0,100000,100000))
np.random.shuffle(A)
B=np.unique(np.random.randint(0,10000,10000))
np.random.shuffle(B)

def find(A,B):
    pos=np.in1d(A,B).nonzero()[0]
    return pos[A[pos].argsort()][B.argsort().argsort()]

In [5]: np.allclose(np.where(np.equal.outer(B,A))[1],find(A,B))
Out[5]: True

In [6]: %time np.where(np.equal.outer(B,A))[1]
Wall time: 3.98 s
Out[6]: array([88220, 13472, 12482, ...,  9795, 39524,  5727], dtype=int64)

In [7]: %timeit find(A,B)
22.6 ms ± 366 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

【讨论】:

    猜你喜欢
    • 2015-08-15
    • 1970-01-01
    • 2011-07-15
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 2021-12-17
    相关资源
    最近更新 更多